4.9.消费端要点介绍
回顾之前介绍了如何正确的消费消息,消费者客户端可以通过推模式或者拉模式的方式来获取并消费消息,当消费者处理完业务逻辑需要手动确认消息已被接收,这样rabbitmq才能把当前消息从队列中标记清除。当然如果消费者由于 某些原因无法处理当前接收到的消息,可以通过channel.basicNack或者channel.basicReject来拒绝掉。
对于rabbitmq消费端来说,还有几点要注意:
1)消息分发
2) 消息顺序性
4.9.1 消息分发
当rabbitmq队列拥有多个消费者时,队列收到的消息将以轮询的分发方式发送给消费者。每条消息只会发送给订阅列表里的一个消费者。这种方式非常适合扩展,而且它是专门为并发程序设计的,如果现在负载加重,那么只需要创建更多的消费者来消费处理消息即可。
默认情况下是取余的方法分发给消息者,如果有n个消费者,m条消息分发,公式(m%n)个消费者。里面有个重要方法,
channel.BasicQos(uint prefetchSize, ushort prefetchCount, bool global);
是指允许限制信道上的消费者所能保持的最大未确认消息的数量。
举例:channel.BasicQos(5)
消费端消费一条消息,没有确认消息,就累加1(确认了减1), 直到累加到5,那么rabbitmq就不会向这个消费者再发送任何消息。
prefetchCount表示最大未确认消息的数量,0表示没有上限。
prefetchSize表示消费者所能接收未确认消息的总体大小的上限,单位为B,0表示没有上限。
global: true 信道上所有的消费者都需要遵从prefetchCount的限定值。 false 信道上新的消费者需要遵从prefetchCount的限定值
无特殊需要,最好只使用gloabl为false的设置,也是默认的设置。
4.9.2 消息的顺序性
是指消费者消费到的消息和发送者发布的消息的顺序是一致的,比如生产者发布消息分别为msg1,msg2,msg3,那么消费者必然也是按照msg1,msg2,msg3的顺序进行消费的。
目前很多资料 显示rabiitmq的消息能够保障顺序性,但有些情况下会打破这种消息的顺序性。
1)事务机制,发送消息之后遇到异常进行了事务回滚,那么需要重新补偿发送这条消息
2) basic.Nack 命令
3)死信队列
4)消息优先级