RocketMQ快速上手(延迟消息队列)


RocketMQ

官方文档:https://rocketmq.apache.org/docs/quick-start/

  1. 解耦 中间件AB

  2. 异步 下单→>成功验证短信、邮件、仓储调度

  3. 消息驱动/事件驱动型

1.开启rocketmq

  1. 添加环境变量
ROCKETMQ_HOME="D:\rocketmq"
NAMESRV_ADDR="localhost:9876"
  1. 在rocketmq的bin目录下开启cmd命令行

输入一下两个命令

mqnamesrv.cmd

启动第一个命令后被阻塞,重新开一个命令行继续输入

mqbroker.cmd -n localhost:9876 autoCreateTopicEnable=true

2 应用

  1. 引入依赖
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.7.0</version>
</dependency>
  1. 添加配置
rocketmq:
  topic: PlaceOrder
  namesrv-addr: 127.0.0.1:9876
  producer:
    producer-group: SleeveProducerGroup
  consumer:
    consumer-group: SleeveConsumerGroup

3 延迟消息队列

预定消息与普通消息的不同之处在于,它们直到指定的时间之后才会被传递。

生产者

@Component
public class ProducerSchedule {

    @Value("${rocketmq.producer.producer-group}")
    private String producerGroup;

    @Value("${rocketmq.namesrv-addr}")
    private String namesrvAddr;
    // rocketmq 的生产者
    private DefaultMQProducer defaultMQProducer;

//    执行顺序: A Construct--> B @Autowired --> @PostConstruct
    @PostConstruct
    public void setDefaultMQProducer() {
        if (defaultMQProducer == null) {
            //在类实例化后,创建defaultMQProducer对象
            this.defaultMQProducer = new DefaultMQProducer(producerGroup);
            // 设置rockemq的地址
            defaultMQProducer.setNamesrvAddr(namesrvAddr);
        }
        try {
            // 开启生成者
            defaultMQProducer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }


    public String send(String topic, String body) throws Exception {
        Message message = new Message(topic, body.getBytes());
        // messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
        // 设置延时级别
        message.setDelayTimeLevel(3);
        // 发送消息
        SendResult sendResult = defaultMQProducer.send(message);

        System.out.println(sendResult.getMsgId());
        System.out.println(sendResult.getSendStatus());
        return sendResult.getMsgId();
    }
}

消费者


/**
 * 实现CommandLineRunner接口的方法 该类由SpringBoot调用
 * 在程序初始化时,只执行一次
 */
@Component
public class ConsumerSchedule implements CommandLineRunner {

    @Value("${rocketmq.consumer.consumer-group}")
    private String consumerGroup;

    @Value("${rocketmq.namesrv-addr}")
    private String namesrvAddr;

    @Value("${rocketmq.topic}")
    private String topic;

    @Autowired
    private OrderCancelService orderCancelService;
    @Autowired
    private CouponBackService couponBackService;

    public void getMessage() throws MQClientException {

        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(consumerGroup);
        // 设置rockemq的地址
        consumer.setNamesrvAddr(namesrvAddr);
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        // 监听test主题下的所有消息
        consumer.subscribe(topic, "*");
        // 并发消费
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                for (MessageExt msg : list) {
                    String orderMessage = new String(msg.getBody());
                    System.out.println(orderMessage);
                    if (StringUtils.isEmpty(orderMessage)) break;
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
    }

    @Override
    public void run(String... args) throws Exception {
        this.getMessage();
    }
}

4 RocketMQ消费位置

public enum ConsumeFromWhere {
    /**
     * 一个新的订阅组第一次启动从队列的最后位置开始消费<br>
     * 后续再启动接着上次消费的进度开始消费
     */
    CONSUME_FROM_LAST_OFFSET,

    @Deprecated
    CONSUME_FROM_LAST_OFFSET_AND_FROM_MIN_WHEN_BOOT_FIRST,
    @Deprecated
    CONSUME_FROM_MIN_OFFSET,
    @Deprecated
    CONSUME_FROM_MAX_OFFSET,
    /**
     * 一个新的订阅组第一次启动从队列的最前位置开始消费<br>
     * 后续再启动接着上次消费的进度开始消费
     */
    CONSUME_FROM_FIRST_OFFSET,
    /**
     * 一个新的订阅组第一次启动从指定时间点开始消费<br>
     * 后续再启动接着上次消费的进度开始消费<br>
     * 时间点设置参见DefaultMQPushConsumer.consumeTimestamp参数
     */
    CONSUME_FROM_TIMESTAMP,
}

4 rocketmq的有序消费模式和并发消费模式的区别

rocketmq消费者注册监听有两种模式,有序消费MessageListenerOrderly和并发消费MessageListenerConcurrently,这两种模式返回值不同。

MessageListenerOrderly正确消费返回ConsumeOrderlyStatus.SUCCESS,

稍后消费返回ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT

MessageListenerConcurrently正确消费返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS

稍后消费返回ConsumeConcurrentlyStatus.RECONSUME_LATER

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ延迟队列是一种在需要延时处理消息的场景下非常有用的机制。在RabbitMQ 3.6.x之前,通常使用死信队列和TTL过期时间来实现延迟队列。然而,从RabbitMQ 3.6.x开始,官方提供了延迟队列的插件,可以方便地下载并安装到RabbitMQ中。\[1\] 使用RabbitMQ来实现延迟队列有许多优势。首先,RabbitMQ具有可靠的消息发送和投递机制,可以确保消息至少被消费一次,并且未被正确处理的消息不会被丢弃。其次,通过RabbitMQ集群的特性,可以解决单点故障问题,即使某个节点挂掉,延迟队列仍然可用,消息也不会丢失。\[2\] 当然,除了使用RabbitMQ的延迟队列插件,还有其他一些选择来实现延迟队列,比如使用Java的DelayQueue、Redis的zset、Quartz或者Kafka的时间轮,每种方式都有其特点,根据具体场景选择适合的方式。\[2\] 要安装RabbitMQ的延迟队列插件,可以从官网下载rabbitmq_delayed_message_exchange插件,并将其解压放置到RabbitMQ的插件目录中。然后,在RabbitMQ安装目录下的plugins目录中执行命令使插件生效,并重启RabbitMQ即可。\[3\] #### 引用[.reference_title] - *1* [RabbitMQ 延迟队列-对于入门来说可以快速上手](https://blog.csdn.net/u011433316/article/details/115003228)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【RabbitMq04】延迟队列](https://blog.csdn.net/weixin_40964170/article/details/119214296)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值