RabbitMQ、RocketMQ、ActiveMQ 、Kafka 四个分布式消息队列的区别 (5)

当autoAck为false的时候,rabbitmq队列会分成两部分,一部分是等待投递给consumer的消息,一部分是已经投递但是没收到确认的消息。如果一直没有收到确认信号,并且consumer已经断开连接,rabbitmq会安排这个消息重新进入队列,投递给原来的消费者或者下一个消费者。

zeromq:不支持,

rocketmq:支持。

消息消费失败的大部分场景下,立即重试99%都会失败,所以rocketmq的策略是在消费失败时定时重试,每次时间间隔相同。

1>发送端的 send 方法本身支持内部重试,重试逻辑如下:

a)至多重试3次;

b)如果发送失败,则轮转到下一个broker;

c)这个方法的总耗时不超过sendMsgTimeout 设置的值,默认 10s,超过时间不在重试。

2>接收端。

Consumer 消费消息失败后,要提供一种重试机制,令消息再消费一次。Consumer 消费消息失败通常可以分为以下两种情况:

由于消息本身的原因,例如反序列化失败,消息数据本身无法处理(例如话费充值,当前消息的手机号被

注销,无法充值)等。定时重试机制,比如过 10s 秒后再重试。

由于依赖的下游应用服务不可用,例如 db 连接不可用,外系统网络不可达等。

即使跳过当前失败的消息,消费其他消息同样也会报错。这种情况可以 sleep 30s,再消费下一条消息,减轻 Broker 重试消息的压力。

activemq:不支持

十七、并发度

Kafka:高

一个线程一个消费者,kafka限制消费者的个数要小于等于分区数,如果要提高并行度,可以在消费者中再开启多线程,或者增加consumer实例数量。

rabbitmq:极高

本身是用Erlang语言写的,并发性能高。

可在消费者中开启多线程,最常用的做法是一个channel对应一个消费者,每一个线程把持一个channel,多个线程复用connection的tcp连接,减少性能开销。

当rabbitmq队列拥有多个消费者的时候,队列收到的消息将以轮询的分发方式发送给消费者。每条消息只会发送给订阅列表里的一个消费者,不会重复。

这种方式非常适合扩展,而且是专门为并发程序设计的。

如果某些消费者的任务比较繁重,那么可以设置basicQos限制信道上消费者能保持的最大未确认消息的数量,在达到上限时,rabbitmq不再向这个消费者发送任何消息。

zeromq:高

rocketmq:高

1>rocketmq限制消费者的个数少于等于队列数,但是可以在消费者中再开启多线程,这一点和kafka是一致的,提高并行度的方法相同。

修改消费并行度方法

a) 同一个 ConsumerGroup 下,通过增加 Consumer 实例数量来提高并行度,超过订阅队列数的 Consumer实例无效。

b) 提高单个 Consumer 的消费并行线程,通过修改参数consumeThreadMin、consumeThreadMax

2>同一个网络连接connection,客户端多个线程可以同时发送请求,连接会被复用,减少性能开销。

activemq:高

单个ActiveMQ的接收和消费消息的速度在1万笔/秒(持久化 一般为1-2万, 非持久化 2 万以上),在生产环境中部署10个Activemq就能达到10万笔/秒以上的性能,部署越多的activemq broker 在MQ上latency也就越低,系统吞吐量也就越高。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwfwdx.html