数据堆积 rocketmq与mysql_rocketMQ(十一) rocketMQ使用 重复消费、消息堆积、顺序消费、消息丢失等问题...

一:顺序发送

通过一定算法,将一组顺序消息发送到同一个broker下面的同一个队列,消费者进行顺序监听即可。

例如:一条信息的唯一标识 通过一定算法 路由到 同一个 broker 下到 某一个队列下。 通过业务层面处理。

// RocketMQ通过MessageQueueSelector中实现的算法来确定消息发送到哪一个队列上

// RocketMQ默认提供了两种MessageQueueSelector实现:随机/Hash

// 当然你可以根据业务实现自己的MessageQueueSelector来决定消息按照何种策略发送到消息队列中

SendResult sendResult = producer.send(msg, new MessageQueueSelector() {

@Override

public MessageQueue select(List mqs, Message msg, Object arg) {

Integer id = (Integer) arg;

int index = id % mqs.size();

return mqs.get(index);

}

}, orderId);

备注:send方法带有参数MessageQueueSelector,MessageQueueSelector是让用户自己决定消息发送到哪一个队列,如果是局部消息的话,用来决定消息与队列的对应关系。

细节:https://www.jianshu.com/p/f8d5a5f37595

二:重复消费

RocketMQ不保证消息不重复,如果你的业务需要保证严格的不重复消息,需要你自己在业务端去重

官方对comsumerMessage方法的实现建议是:

It is not recommend to throw exception,rather than returning ConsumeConcurrentlyStatus.RECONSUME_LATER if consumption failure

无论如何,都不要抛出异常,如果需要重新消费,可以返回RECONSUME_LATER主动要求重新消费。

三:消息堆积

其实对于一个原本正常的消息系统来说消息积压,只会出现两种情况:要么生产者消息数量增加导致的积压;要么就是消费者消费变慢导致的消息积压。对于一个消息队列我们肯定在上线前就预估好,单节点最大承受流量与系统目前最大峰值流量的数据,一般情况下消息队列收发性能是远大于业务处理性能的,一旦出现的话问题也很显而易见:要么就是流量突然增加,要么就是业务逻辑异常。我能应该从三个方面来查找问题:

生产端:一般当生产端发生积压(Broker正常的情况下)就要查看你的业务逻辑是否有异常的耗时步骤导致的。是否需要改并行化操作等。

Broker端:当Broker端发生积压我们首先要查看,消息队列内存使用情况,如果有分区的的话还得看每个分区积压的消息数量差异。当每个分区的消息积压数据量相对均匀的话,我们大致可以认为是流量激增。需要在消费端做优化,或者同时需要增加Broker节点(相当于存储扩容),如果分区加压消息数量差异很大的话(有的队列满了,有的队列可能还是空闲状态),我们这时候就要检查我们的路由转发规则是否合理,

消费端:在使用消息队列的时候大部分的问题都出在消费端,当消费速度小于生产速度很快就会出现积压,导致消息延迟,以至于丢失。这里需要重点说明一点的是,当消费速度小于生产速度的时候,仅增加消费者是没有用处的,因为多个消费者在同一个分区上实际是单线程资源竞争关系(当然还有一些冒险的单队列多消费者并行方式就是:消费者接到消息就ack成功再去处理业务逻辑,这样你就要承受消息丢失的代价),我们需要同时增加Broker上的分区数量才能解决这一问题。

那么上面我们说到消息积压的问题所在,那么遇到这样问题我们怎么能够快速的解决呢?我们需要查看是否有无限重发的消息或者有进入死锁的程序等等,当确定是流量激增的话,我们需要评估是否需要增加资源还是通过限流的方式解决,当短时间大量消息需要处理时,在资源允许的情况下,我们可以新启一批消费者与消息队列,将原来的消费者中的消息直接作为生产者转发到临时应急队列中,这样大概率的能够快速解决消息积压。与其事后处理不如我们在设计之初就要把积压考虑进来,对于数据量非常大,但是实时性要求不高的场景,可以设计出批量消息发送,当队列积累到一定阀值再做批量消费消费,这里需要注意的就是重复消费带来的影响,设计不好就是一场灾难。

来源: https://zhuanlan.zhihu.com/p/112681372

四:消息丢失(消息重试)

主要分为生产端和消费端

生产端:可以指定发送次数,失败后 异常处理

消费端:重试-进行重新消费问题(注意幂等性问题,数据库或者分布式锁) 。 一般指定次数。超过限制则记录 日志表 进行人工补偿机制

细节看 https://www.jianshu.com/p/09d13c70ddad

注意:默认情况下CommitLog在每天4点删除超过48小时的文件或者当磁盘水位线达到75%。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值