rocketMQ总结(一)

常见问题汇总

1、RocketMQ,不同Group的消费者能消费相同topic的消息

图片讲解11

2、RocketMQ中对同一个消费组设置不同的tag订阅关系,出现消息丢失的问题

官方告诉使用者:同一个消费组,必须保持订阅关系一致
图片讲解21

丢失原因分析:

图片讲解22

同组消费实例订阅不同topic丢失原因总结

同一组订阅topic 不一致,也会造成消息部分不消费;由于负载均衡消费,分发消息给了各个实例,而有的消费者实例刚好不是订阅该主题的。

消息过滤实现机制

消费端队列存储的是 tag 的 hashcode,不同的字符串得到的hashcode值可能一样,故在服务端是无法精确对消息进行过滤的,所以在RocketMQ中会进行两次消息过滤。

当客户端向服务端拉取消息时,服务端在返回消息之前,会先根据hashcode进行过滤,然后客户端收到服务端的消息后,再根据消息的tag字符串进行精确过滤。

那为什么会丢失消息呢?这其实和消息队列负载机制有关.

在RocketMQ中使用集群模式消费时,同一个消费组中的多个消费者共同完成主题中的队列的消费,即一个消费者只会分配到其中某几个队列,并且同一时间,一个队列只会分配给一个消费者,这样结合上面的的过滤机制,就会明显有问题,请看示例图:

讲解图片23
其问题的核心关键是,同一个tag会分布在不同的队列中,但消费者C1分配到的队列为q0,q1,q0,q1中有taga和tagb的消息,但tagb的消息会被消费者C1过滤,但这部分消息却不会被C2消费,造成了消息丢失。

3、一个消费实例中是可以多线程处理消费消息的

单实例消费者也是多线程消费的,线程池默认最小线程20个,无界队列,所以不会开到最大64个线程,最多就20个线程消费

一个消费者实例拉取的消息数如果大于分批处理数,就分成多批给多个线程进行处理

4、rocketMQ 消费进度问题

rocketmq 进度更新,不受消费失败的影响,继续前进?

rocketMQ本地消费缓存队列偏移量: 消费缓存偏移量即以最小消费成功或者消费失败但成功回发重试消息的偏移量为准

不断消费更新本地缓存偏移量; broker上的远程偏移量是 异步线程检测操作进行远程更新的,并不是同步

消费端有拉取消息队列:不断循环拉取消息来进行消费;根据拉取进度进行循环拉取,不是以消费进度进行拉取; 与本地缓存消费队列 消费进度不同,后者是作用于更新服务端消费偏移量

因此,宕机等因素,可能导致服务端已消费偏移量不同步,导致重启后出现重复拉取消费的情况

消费者消费失败后,消息如何处理?

消费失败后,消费端会回发消费失败的消息(topic是不一样)给broker,broker收到后交给定时任务,由定时任务根据延迟消费策略,进行定时推送消费消息

5、rocketMQ 默认消费模式是 push or pull 模式?

就两种消费模式:push模式和pull模式;默认消费模式是push模式
其实,严格意思上,rocketMQ并没有实现push模式,而是对拉模式进行了一种包装。
push原理:消费端通过pull不断轮询broker获取消息。不存在新消息时,broker挂起消费端请求,直到有新消息,取消挂起,返回新消息给消费端。这样,基本和broker主动push做到接近的实时性。原理类似长轮询

两种模式各自优缺点

(1)pull 方式
优点:理论上可以减轻服务端压力
缺点:设置合适拉取消息的频率成为难点。设置的时间间隔过长,消息就可能有所延迟消费,并造成MQ服务端堆积的消息变多;设置过短,可能会产生很多无效的pull请求,造成一定的开销,影响整体性能
(2)push 方式
优点:主动推消息给消费端,可以让客户端比较实时的消费消息,延迟较小
缺点:在消费者处理消息较弱的时候,或处理单条消息耗时过长,会引起问题。慢消费问题,在MQ不断push消息到消费端,会可能导致消费端的缓冲区溢出,从而引起系统异常

6、rocketMQ再平衡过程中,是如何避免两个消费实例消费同一队列,即存在重复消费消息问题?

为啥会存在两个消费实例消费同一消息队列?

如果某个消费者网络不稳定等,导致其他消费者认为其掉线了,那么可能出现同一个时刻,有两个消费者同时消费同一个队列的情况。
再平衡过程是由消费端各自处理的、但执行会有先后快慢(毕竟是个定时任务,各自起始启动时间不一)。这样,就会造成一个消费端再平衡后,拥有了另一个还没来得及执行再平衡的消费端的某些消息队列。因此,有可能会造成重复消费问题

这种情况下,MQ是如何避免重复消费问题?

为防止两个消费实例重复消费同一队列同一消息,rocketMQ提供了对broker上的队列加锁的功能,消费端只有加锁才能进行消费,加锁后定时任务在锁过期前,又重复加锁,延长锁定时间,这样就避免了同时消费、重复消费问题。
ConsumeRequest的run()方法下有个判断:

this.processQueue.isLocked() && !this.processQueue.isLockExpired()

这个判断便是校验是否已经对broke上的队列加锁了,如果没有加锁,则禁止消费消息,需要执行else里面的逻辑:

ConsumeMessageOrderlyService.this.tryLockLaterAndReconsume(this.messageQueue, this.processQueue, 100);

tryLockLaterAndReconsume()会创建一个定时任务,定时任务完成两件事:
(1)向broker发送LockBatchRequestBody请求,请求将该broker上当前消费者消费的队列加锁;
(2)加锁成功后,重新调用submitConsumeRequest(),开启线程重新处理消息。

除了上面这种方式加锁之外,消费者还有一个定时任务,每隔20s启动一次,它是由ConsumerMessageOrderlyService.lockMQPeriodically()触发的,该任务获取当前消费者正在消费的所有队列,然后向这些队列所在的broker发送LockBatchRequestBody请求,请求对这些队列加锁。
无论是通过定时任务还是其他方式加锁,每次加的锁的过期时间是30s。而且同一个消费者可以重复对一个队列进行加锁。
在broker上对队列加的锁,消费者是不主动释放的,也就是说一个消费者加了锁之后,只能等待锁超时,然后大家再去竞争锁。消费者只有一种情况会主动释放锁,就是消费者消息消费结束,主动调用shutdown方法关闭。

7、消费确认,自动 or 手动?

rocketmq

仅支持手动确认。
消费手动确认前,业务逻辑发生异常,消息未成功消费,后续消费重试。

rabbitmq

同时具有自动确认和手动确认。
自动确认:不在乎消费者对消息处理是否成功,都会告诉队列删除消息。如果处理消息失败,实现自动补偿(队列投递过去,重新处理)
手动确认: 确认后才删除消息

kafaka

待补充

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我可以用Java来写一个RocketMQ延迟消息的例子。首先,您需要配置RocketMQ的环境,然后创建一个Producer实例,并且设置消息的属性,将消息发送到指定的topic。在发送消息时,可以设置消息的延迟时间,使用sendDelayMsg()方法,消费者将在指定的时间后收到消息。 ### 回答2: RocketMQ是一个开源的分布式消息队列系统,在实现延迟消息时可以使用RocketMQ提供的特性——延迟消息。延迟消息是指在发送消息时可以指定该消息的延迟时间,消息会在指定延迟时间之后才会被消费者消费。 要写一个RocketMQ延迟消息,首先需要搭建一个RocketMQ的环境,包括安装RocketMQ服务器和创建Producer和Consumer。然后,按照以下步骤实现延迟消息: 1. 创建Producer:在程序中创建一个RocketMQ的Producer对象,设置NameServer的地址,并启动Producer。 2. 创建延迟消息:使用Producer创建一个延迟消息,包括指定Topic和Tags,并在消息中设置延迟时间,单位为毫秒。 3. 发送消息:使用Producer发送延迟消息。 4. 创建Consumer:在程序中创建一个RocketMQ的Consumer对象,设置NameServer的地址和要消费的Topic,并启动Consumer。 5. 消费消息:Consumer会从RocketMQ服务器中拉取消息,当延迟时间到达时,消费者会收到消息并进行消费。 需要注意的是,RocketMQ的延迟消息有一定的误差,实际的延迟时间可能比设置的延迟时间要长。这是因为消息的发送和消费都需要一定的时间,以及网络延迟等因素的影响。 总结起来,实现RocketMQ延迟消息需要搭建RocketMQ环境,创建Producer和Consumer,并在消息中设置延迟时间。通过这些步骤,即可实现RocketMQ延迟消息的功能。 ### 回答3: RocketMQ是一个分布式消息队列系统,可以实现可靠的消息传递和事务消息等。要写一个RocketMQ延迟消息,可以按照以下步骤进行: 1. 首先,确保已经正确设置了RocketMQ的环境和配置,并创建了所需的生产者和消费者。 2. 创建一个Topic(主题)和一个Tag(标签),以便将延迟消息发送到正确的目标。 3. 在生产者端创建消息,并设置延迟时间。可以使用`ScheduleMessage`类的`setDelayTimeLevel`方法来设置延迟级别,取值范围为1-18,代表延迟时间分别为1s、5s、1m、2m等。 4. 将设置好延迟时间的消息发送到指定的Topic和Tag。 5. 在消费者端,通过订阅指定的Topic和Tag,接收延迟消息。 6. 消费者接收到延迟消息后,根据业务需求进行相应的处理。 需要注意的是,RocketMQ的延迟消息依赖于Broker的定时任务,默认会每隔1秒扫描所有的延迟消息并发送。 综上所述,以上是一个简单的描述如何写一个RocketMQ延迟消息的步骤。具体实现时,需要按照RocketMQ的API文档和具体业务需求进行操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值