消费者获取消息主要有push和pull两种模式算法
push模式: 由消息队列主动向 Consumer 推送消息服务器
pull模式: 由 Consumer 主动从消息队列 获取消息并发
push模式最大的缺点就是:服务器不清楚consumer的消费速度,若是consumer中执行的操做又是比较耗时的,那么consumer可能会不堪重负,而性能好的consumer可能处于闲置状态,形成负荷·不均。异步
pull模式最大的缺点应该就是: 当部分consumer异常致使 Producer 速度远大于consumer速度时,大量消息会堆积在消息队列中。至于说影响实时性的问题,实际上是能够经过实现的方式进行解决。性能
对比两种方式,通常的消息队列都会采用pull模式,他有一下优势:spa
一、consumer根据自身能力进行获取任务,按照多劳多得的原则,能够解决多个服务器之间负荷不均的问题。队列
二、消息有消息队列统一管理,能够作消息备份,保证消息不丢失。路由
consumer采用pull模式的实现方案kafka
一、consumer启动后向消息队列发送准备就绪,而后异步等待任务消息队列
二、consumer定时向消息队列发送心跳包
三、消息队列收到心跳包后更新consumer的有效性,消费者一段时间未更新则移除,防止consumer异常退出后,继续下发任务。
四、 消息队列接受到任务后采用最近最少使用算法路由(LRU模式) 将任务转发给consumer
五、现实中consumer处理任务不会是处理完一个再接下一个,所以,能够采用多通道模式,即准备就绪信号携带通道id,这样一来能够经过控制通道数就能够控制任务处理的并发数。
这里还有一个问题就是,当consumer异常结束时,未处理完成的消息要如何处理,这里就要看是由消息队列维护状态信息仍是由consumer来维护状态信息,好比kafka就采用的由consume维护状态信息,consume记录消息的偏移量,异常重启后能够重写获取消息。若是是由消息队列维护队列状态,那么能够将正在执行的任务进行记录,若是检测到consumer异常退出,就能够将任务回收进行重发,但这里并不能肯定consumer全部待处理的消息是否须要重发,所以这里须要更加实际业务进行处理。