消息队列RocketMQ入门实践--关键特性(三)

系列文章目录

消息队列RocketMQ入门实践(一)
消息队列RocketMQ入门实践(二)



前言

嗨,大家好,我是希留。

经过前面两篇文章的学习,相信大家对RocketMQ已经有了一个基本的了解了,这篇文章就来说一说RocketMQ的几个关键特性,废话不多说,咱开始吧。

项目源码:Gitee地址


一、顺序消息

在有的业务中,consumer在消费消息时,是需要按照生产者发送消息的顺序进行消费的,比如在电商系统中,订单的消息,会有创建订单、订单支付、订单完成,如果消息的顺序发生改变,那么这样的消息就没有意义了。

1.1 顺序消息的原理

在这里插入图片描述
要保证消息的顺序消费,有三个关键点:

  • (1)消息顺序发送
  • (2)消息顺序存储
  • (3)消息顺序消费

第一点,消息顺序发送,多线程发送的消息无法保证有序性,因此,需要业务方在发送时,针对同一个业务编号(如同一笔订单)的消息需要保证在一个线程内顺序发送,在上一个消息发送成功后,在进行下一个消息的发送。对应到mq中,消息发送方法就得使用同步发送,异步发送无法保证顺序性

第二点,消息顺序存储,mq的topic下会存在多个queue,要保证消息的顺序存储,同一个业务编号的消息需要被发送到一个queue中。对应到mq中,需要使用MessageQueueSelector来选择要发送的queue,即对业务编号进行hash,然后根据队列数量对hash值取余,将消息发送到一个queue中

第三点,消息顺序消费,要保证消息顺序消费,同一个queue就只能被一个消费者所消费,因此对broker中消费队列加锁是无法避免的。同一时刻,一个消费队列只能被一个消费者消费,消费者内部,也只能有一个消费线程来消费该队列。即,同一时刻,一个消费队列只能被一个消费者中的一个线程消费

1.2 代码示例

生产者代码示例如下:

public class OrderProducer {
   

    public static void main(String[] args) throws Exception{
   
        DefaultMQProducer producer = new DefaultMQProducer("xiliu_producer_group");
        producer.setNamesrvAddr("42.194.222.32:9876");
        producer.start();

        for (int i = 0; i<100; i++) {
   
            String msgStr = "order -->" + i;
            // 模拟生产订单id
            int orderId = i % 10;

            Message message = new Message("broker-a","order_msg",msgStr.getBytes(RemotingHelper.DEFAULT_CHARSET));

            SendResult sendResult = producer.send(message,(mqs, msg, arg) -> {
   
                    Integer id = (Integer) arg;
                    int index = id % mqs.size();
                    return mqs.get(index);
                    }<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java升级之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值