RocketMQ顺序消费

RocketMQ通过局部顺序一致性确保消息发送顺序,同一队列仅由一个线程消费以保持顺序,同时允许多队列并行消费提高效率。生产者实现MessageQueueSelector分配策略,消费者采用MessageListenerOrderly保证每个队列顺序消费。测试结果显示不同队列无序,但单个队列内有序。
摘要由CSDN通过智能技术生成

一、rocketmq顺序消费的原理

1、消息的有序性是指消息的消费顺序能够与消息的发送顺序一致。但是有时候我们从业务需要上面并不需要保证所有消息严格按照消费顺序完全一致。例如,一个订单的下单、付款、出库等操作是不同替换顺序。但是有A订单和B订单,并不需要保证A订单与B订单的顺序。

2、RocketMQ采用了局部顺序一致性的机制,一组消息发送到同一个队列中来保证发送顺序的有序性,然后再由消费者进行。消费的时候通过一个队列只会被一个线程取到 ,第二个线程无法访问这个队列 来保证队列有序性。rocketmq可以同时多个队列并列消费提高,提高rocketmq的消费速度。其实这个方案很像jdk7 里面ConcurrentHashMap 实现分段锁的实现,通过保证每段的线程安全,多段并行消费提高消费能力。

二、代码的具体实现

1、引入依赖

<!-- https://mvnrepository.com/artifact/org.apache.rocketmq/rocketmq-client -->
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
            <version>4.2.0</version>
        </dependency>

生产方:

2、rocketmq 生产者的配置文件

###producer
#该应用是否启用生产者
rocketmq.producer.isOnOff=on
#发送同一类消息的设置为同一个group,保证唯一,默认不需要设置,
# rocketmq会使用ip@pid(pid代表jvm名字)作为唯一标示
rocketmq.producer.groupName=rocketProducerGroup
#mq的nameserver地址
rocketmq.producer.addr=192.168.25.128:9876
#消息最大长度 默认1024*4(4M)
rocketmq.producer.maxMessage=4096
#发送消息超时时间,默认3000
rocketmq.send.outTime=3000
#发送消息失败重试次数,默认2
rocketmq.producer.retryNum=2

rocketmq.producer.topic=orderTopi

rocketmq.producer.tag=demoTag

2、生产者的配置类

@Configuration
@Component
public class RocketProduceConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(RocketProduceConfig.class);
    /**
     * 发送同一类消息的设置为同一个group,
     * 保证唯一,默认不需要设置,rocketmq会使用ip@pid(pid代表jvm名字)作为唯一标示
     */
    @Value("${rocketmq.producer.groupName}")
    private String groupName;

    @Value("${rocketmq.producer.addr}")
    private String producerAddr;
    /**
     * 消息最大大小,默认4M
     */
    @Value("${rocketmq.producer.maxMessage}")
    private Integer maxMessageSize;
    /**
     * 消息发送超时时间,默认3秒
     */
    @Value("${rocketmq.send.outTime}")
    private Integer sendMsgTimeOut;
    /**
     * 消息发送失败重试次数,默认2次
     */
    @Value("${rocketmq.producer.retryNum}")
    private Integer retryNum;

    @Bean
    public DefaultMQProducer getRocketMQProducer() throws RocketMQException {



        DefaultMQProducer producer = new DefaultMQProducer(this.groupName);

        producer.setNamesrvAddr(this.producerAddr);
        //如果需要同一个jvm中不同的producer往不同的mq集群发送消息,需要设置不同的instanceName
        //producer.setInstanceName(instanceName);
        if(this.maxMessageSize!=null){
            producer.setMaxMessageSize(this.maxMessageSize);
        }
        if(this.sendMsgTimeOut!=null){
            producer.setSendMsgTimeout(this.sendMsgTimeOut);
        }
        //如果发送消息失败,设置重试次数,默认为2次
        if(this.retryNum!=null){
            producer.setRetryTimesWhenSendFailed(this.retryNum);
        }

        try {
            producer.start();

            LOGGER.info("producer is start, g
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值