消息队列好处:
队列好处:异步处理(提高响应速度,后续可以批量处理)、流量削峰(平滑流量)、应用解耦。
通过异步技术可以提升主流程响应速度。比如用户注册成功之后,发送注册成功邮件。非主流程可以集中批量处理。再例如:用户支付成功后,需要通知配货系统。只需要放入消息队列,之后需要做哪些工作,发送消息的应用不需要知道,即应用解耦了。
RabbitMQ消息队列
RabbitMQ符合AMQP(消息队列的一个标准),还支持STOMP、MQTT。
支持消息持久化。消息消费支持推和拉两种模式。消息可以设置TTL过期时间。
使用ErLang开发。它是一种解释型语言。所以运行RabbitMQ需要Erlang环境。API支持语言包括Java、Python、C#、JavaScript、PHP、Ruby。
QoS等级只有0和1,不支持2。所以一些场景会出现消息重复接收,需要在业务层面进行防重复的处理。
QoS等级为1时,消息服务器将消息放置在合适的队列中后,会回复发送者confirm消息。消费者消费完成会回复ack给消息服务器。
RabbitMQ原理:
RabbbitMQ中,生产者和队列之间有Exchange,Exchange负责将消息路由到队列上。
一个RabbitMQ服务器可以有多个Exchange。
RabbitMQ中有channel和Connection的概念。Connection是指一条TCP连接。多个AMQP channel复用同一条TCP连接,使用channel ID区分。这样可以减少TCP连接建立和销毁的开销。一个应用程序中的每个线程使用一个channel。
生产者的发送消息时指定了exchange,broker将消息交给指定的exchange。生产者发送消息是还指定了routing key。
BindingKey(绑定键):队列绑定交换器时指定的key。
消息的Routing key和队列的binding key匹配时,消息会被路由到相应的队列。如果路由不成功,会通知生产者。
消费者收到消息后会回复ACK给broker。消息服务器收到ack后,删除消息。
RabbitMQ主要有3种交换器:
Fanout:将消息路由给所有队列。
Direct:如果消息routing key和队列的binding key完全相同,则把消息发送给这个队列。一条消息可以发给多个队列。
Topic:与Direct的不同在于,不要求routing key和binding key完全相同,允许模糊匹配。约定Routing key和binding key是点号分隔的单词组成的字符串,比如com.job.work。可以使用*和#进行模糊匹配,*用来匹配一个单词,#用来匹配0个、1个和多个单词。一条消息可以发给多个队列。
发布订阅模式:
消费者指定exchange和routing-key,通常不指定队列,由消息服务器去创建队列。
每个消费者只能消费一个队列中的消息。一个队列可以有多个binding key。
队列中一个消息只能供一个消费者消费。如果多个消费者都需要消费同一种routing key的消息,exchange可以将这种消息发送给多个队列。
work queue模式:
用作work queue时,多个worker指定同一个队列,不指定exchange(实际上是默认exchange),允许多个worker执行同一个队列中的任务。使用round-robin方式依次将消息发给各个worker。
RPC模式:
要用一对消息队列,一个用于请求路径,另一个用于应答路径。
性能监控:通过http管理API来查看消息队列中队列数量,从而判断出是否存在消息积压。返回的是application/json数据。