RocketMQ是如何保证顺序消费的 fca34b173b8346ef9a92d7a3176a86f1

RocketMQ是如何保证顺序消费的

为什么需要顺序消费?

在订单业务中,有以下几个消息,订单创建 订单发货 订单收货 订单完成,这几个消息需要顺序生产和顺序消费,否则是不合业务逻辑的。

如何保证顺序消费?代码中如何实现?

第一、生产者保证(部分)有序

全部有序和部分有序是什么?区别是什么?

全部有序:

订单1创建 订单1发货 订单1收货 订单1完成 订单2创建 订单2发货 订单2收货 订单2完成 …

订单n创建 订单n发货 订单n收货 订单n完成

全部有序必须要用单队列实现,如下图,

在这里插入图片描述

但我们都知道所有的消息中间件都是集群式部署的,不同的Broker上有不同的队列,所以单队列实现全部有序是不可能的。

部分有序:

将有序的一组消息(比如订单1创建 订单1发货 订单1收货 订单1完成)放入同一个队列。如下图

在这里插入图片描述

那么怎么实现将有序的一组消息放入同一个队列呢?

可以用同一个订单id的哈希值作为队列索引,会根据订单id的哈希值计算这个消息发到哪一个队列中去,从而实现同一个订单id的消息发到同一个队列中。

代码实现如下:

**/**
 * 发送同步顺序消息
 */
public void sendOrderlyMessage(){
	// hashKey用来计算决定消息发送到哪个消息队列 一般是订单ID,产品ID等
	rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456231,创建", "98456231");
	rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456231,支付", "98456231");
	rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456231,完成", "98456231");

	rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456232,创建", "98456232");
	rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456232,支付", "98456232");
	rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456232,完成", "98456232");
}**

第二、消费者保持顺序消费

rocketmq默认是多线程消费,多个消费者会去并发地消费多个队列中的消息,没有办法保证消息有序型。

RocketMQ设置消费模式为ConsumeMode.ORDERLY,给每一个队列加分布式锁(类似于concurrentHashMap分段segement加锁),保证同一时刻只能有一个线程去消费一个队列中的消息;加锁消耗性能的。

/**
 * 监听顺序消息,保证顺序缴费
 */
@Component
@Slf4j
@RocketMQMessageListener(topic = "orderTopic", consumerGroup = "ordered-consumer",consumeMode = ConsumeMode.ORDERLY)
 
public class OrderedMsqConsumer implements RocketMQListener<String> {
    @Override
    public void onMessage(String message) {
        log.info("consumer 顺序消费,收到消息{}",message);
    }
}

总之,RocketMQ 的做法就是分区有序性,首先需要发送者,将有顺序的消息发往 Topic 下同一个 MessageQueue,然后消费者,顺序地一个一个进行消费,消费失败将会一直重试,前面消息消费完成才能进行下一个,所以需要在业务上确保消息失败机制,避免消息阻塞。

ref:

rocket顺序消费

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值