RabbitMQ队列类型
Rabbit主要有以下5种消息队列:
- 点对点队列模式(简单)
- 工作队列模式(公平性)
- 发布订阅模式
- 路由模式Routing
- 通配符模式Topics
1. 点对点队列
功能:一个生产者投递消息给队列,只能允许有一个消费者进行消费。
流程图:
推拉模式:
- 推:消费者已经启动了,建立长连接,一旦生产者向队列投递消息会马上推送给消费者。
- 拉:生产者先投递消息到队列进行缓存,这时候消费者再启动的时候就会向队列获取消息。
应答模式:
- 自动应答:不在乎消费者对这个消息处理是否成功,都会告诉队列删除消息,如果处理消息失败的情况下,实现自动补偿。
- 手动应答:消费处理完业务逻辑,手动返回ACK(通知)告知对队列服务器是否删除该消息。
为了确保消息不会丢失,RabbitMQ支持消息应答。消费者发送一个消息应答,告诉RabbitMQ这个消息已经接收并且处理完毕了。RabbitMQ就可以删除它了
如果一个消费者挂掉却没有发送应答,RabbitMQ会理解为这个消息没有处理完全,然后交给另一个消费者去重新处理。这样,你就可以确认即使消费者偶尔挂掉也不会丢失任何消息了。
没有任何消息超时限制;只有当消费者挂掉时,RabbitMQ才会重新投递。即使处理一条消息会花费很长的时间。
消息应答是默认打开的。我们通过显示的设置
autoAsk=true
关闭这种机制。现即自动应答开,一旦我们完成任务,消费者会自动发送应答。通知RabbitMQ消息已被处理,可以从内存删除。如果消费者因宕机或链接失败等原因没有发送ACK(不同于ActiveMQ,在RabbitMQ里,消息没有过期的概念),则RabbitMQ会将消息重新发送给其他监听在队列的下一个消费者
2. 工作队列模式
功能:队列服务器向消费者发送消息的时候,消费者采用手动应答模式,队列服务器必须要接到消费者发送ack结果通知,才会继续发送下一个消息。工作队列称为“能者多劳队列”,谁应答的快,谁就能多消费信息。
流程图:
工作模式(默认消费者集群均摊消费):
- 假设生产者向队列发送10个消息,消费者1和消费者2都各自消费5个,保证了消费的唯一性。
弊端:
- 均摊消费会带来一些弊端:如果每个消费者处理消费的业务时间不相同的情况,可能对消费者处理比较慢的服务器不公平。
RabbitMQ的公平转发:
目前消息转发机制是平均分配,这样就会出现俩个消费者,奇数的任务很耗时,偶数的任何工作量很小,造成的原因就是近当消息到达队列进行转发消息。并不在乎有多少任务消费者并未传递一个应答给RabbitMQ。仅仅盲目转发所有的奇数给一个消费者,偶数给另一个消费者。
为了解决这样的问题,我们可以使用basicQos方法,传递参数为
prefetchCount= 1
,这样告诉RabbitMQ不要在同一时间给一个消费者超过一条消息。
换句话说,只有在消费者空闲的时候会发送下一条信息。调度分发消息的方式,也就是告诉RabbitMQ每次只给消费者处理一条消息,也就是等待消费者处理完毕并自己对刚刚处理的消息进行确认之后,才发送下一条消息,防止消费者太过于忙碌,也防止它太过去清闲。(
通过设置channel.basicQos(1);
)
3. 发布订阅模式
功能:一个生产者发送消息,多个消费者获同样的消息(包括一个生产者、一个交换机、多个队列、多个消费者)。
流程图:
「点对点」和「工作队列模式」都是消息只能发送到指定的queue中,但是想要类似广播的效果,发给所有消费者,这时候就需要用到交换机(exchange)了。
部分代码说明:
1.fanout:所有bind到此exchange的queue都可以接收消息。
2.direct: 通过routingKey和exchange决定的那个唯一的queue可以接收消息。
3.headers: 通过headers 来决定把消息发给哪些queue。
4.topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息。表达式符号说明:
#代表一个或多个字符,*代表任何字符 例: #.a会匹配a.a,aa.a,aaa.a等 *.a会匹配a.a,b.a,c.a等 注:使用RoutingKey为#,Exchange Type为topic的时候相当于使用fanout
注意:交换机没有存储消息功能,如果消息发送到没有绑定消费队列的交换机,消息则丢失。
4. 路由模式Routing
功能: 生产者发送消息到交换机并指定一个路由key,消息队列绑定到交换机时要指定路由key(key匹配就能接收消息,key不匹配就不能接收消息)。
流程图:
这其实就是Direct组播模式,设置好Exchange交换机的类型,转发的时候,会检查队列中的RoutingKey值,如果和消息的关键字相同则转发,否则丢弃。
5. 通配符模式Topics
功能: 此模式是在路由模式的基础上,使用了通配符来管理消费者接收消息。生产者发送消息到交换机,交换机根据绑定队列的RoutingKey的值进行通配符匹配;
通配符模式,其实和路由模式相类似,但是这个支持模糊匹配。
例如:
符号#:匹配一个或者多个词lazy.# 可以匹配lazy.irs或者lazy.irs.cor
符号*:只能匹配一个词lazy.* 可以匹配lazy.irs或者lazy.cor