Spring Boot【4】整合Rocket MQ

前言

    本博文只讲述如何在Spring Boot工程中使用Rocket MQ,并不涉及原理,有需求者可跳转下方博文。

【附】博文:《Rocket MQ(1):简介》

一 准备工作

1.依赖

    很多文章在讲述整合Rocket MQ时都会使用原生API依赖。这么做固然可行,但大量的底层配置及复杂的操作代码不利于Rocket MQ在企业内的推广和项目的整体维护。

        <!--   Rocket MQ客户端依赖(不推荐) -->
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
            <version>4.4.0</version>
        </dependency>

    推荐采用【rocketmq-spring-boot-starter】依赖。这是一个年轻的项目,2019年1月正式收纳于Maven中心仓库,截至2021年6月共7个版本。该项目完成了整合的大量底层工作,并提供了喜闻乐见的Spring起步依赖包:

        <!--  Spring Boot工程Rocket MQ起步依赖(推荐)  -->
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>
2.配置
# Rocket MQ configuration
rocketmq:
  // 命名服务器地址。
  nameServer: http://localhost:9876
  producer:
    // 生产者组名称,此处直接使用服务名。
    group: ${spring.application.name}
    // 发送消息超时时间,默认3s(因此也可不设置)。
    send-message-timeout: 3000

二 消费者

1.消费监听
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

/**
 * @Author: 说淑人
 * @Description: consumerGroup:消费组名称。自定义且唯一,否则会报错。
 * @Description: topic:主题。指定消费消息的主题。
 * @Description: selectorExpression:筛选,无tag时可不设置。
 * @Description: 指定消费消息的标签,不设置或为默认值(*)时消费topic下所有消息。
 * @Description: 泛型:指定消费消息的类型。
 */
@Slf4j
@Component
@RocketMQMessageListener(consumerGroup = "consumerGroup",
        topic = "topic", selectorExpression = "tag")
public class Consumer implements RocketMQListener<String> {

    /**
     * 处理消息
     *
     * @param message 消息
     */
    @Override
    public void onMessage(String message) {
        Thread thread = Thread.currentThread();
        log.info("线程【ID:" + thread.getId() + ",名称:" + thread.getName() + "】开始执行处理消息监听器.....");
        log.info(message);
        log.info("线程【ID:" + thread.getId() + ",名称:" + thread.getName() + "】结束执行处理消息监听器。");

    }

}
2.消费模式
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

/**
 * @Author: 说淑人
 * @Description: consumerGroup:消费组名称。自定义且唯一,否则会报错。
 * @Description: topic:主题。指定消费消息的主题。
 * @Description: selectorExpression:筛选,无tag时可不设置。
 * @Description: 指定消费消息的标签,不设置或为默认值(*)时消费topic下所有消息。
 * @Description: messageModel:消息模式。指定消费消息的模式。
 * @Description: 泛型:指定消费消息的类型。
 */
@Slf4j
@Component
@RocketMQMessageListener(consumerGroup = "consumerGroup",
        topic = "topic", selectorExpression = "tag",
        // MessageModel.CLUSTERING:集群模式(默认);
        // MessageModel.BROADCASTING:广播模式。
        messageModel = MessageModel.BROADCASTING)
public class Consumer implements RocketMQListener<String> {

    /**
     * 处理消息
     *
     * @param message 消息
     */
    @Override
    public void onMessage(String message) {
        Thread thread = Thread.currentThread();
        log.info("线程【ID:" + thread.getId() + ",名称:" + thread.getName() + "】开始执行处理消息监听器.....");
        log.info(message);
        log.info("线程【ID:" + thread.getId() + ",名称:" + thread.getName() + "】结束执行处理消息监听器。");

    }

}

三 简单发送

1.同步发送
    /**
     * 同步发送
     */
    private void syncSend() {
        // 终点:即消息的键。由topic和tag(可无)通过:连接而成,例topic:tag、topic。
        String destination = "topic:tag";
        // 消息:即消息的值。是要发送的内容,可为任意类型,此处用String。
        String message = "Hello World";
        // 方法一。
        SendResult sendResult = rocketMQTemplate.syncSend(destination, MessageBuilder.withPayload(message).build());
        // 方法二。
        sendResult = rocketMQTemplate.syncSend(destination, message);
        // 以上两种方法都可完成发送,其中方法一是方法二的底层方法。本人习惯用第二种,因为操作方便。
    }
2.异步发送
    /**
     * 异步发送
     */
    private void asyncSend() {
        // 终点:即消息的键。由topic和tag(可无)通过:连接而成,例topic:tag、topic。
        String destination = "topic:tag";
        // 消息:即消息的值。是要发送的内容,可为任意类型,此处用String。
        String message = "Hello World";
        // 发送回调接口对象:用于异步处理发送结果。
        SendCallback sendCallback = new SendCallback() {

            /**
             * 处理成功
             * @param sendResult 发送结果对象
             */
            @Override
            public void onSuccess(SendResult sendResult) {
                // 发送成功时执行逻辑。
            }

            /**
             * 处理成功
             * @param throwable 错误对象
             */
            @Override
            public void onException(Throwable throwable) {
                // 发送失败时执行逻辑。一般是将失败数据入库,采用定时的方式尝试再次发送。
            }

        };
        // 方法一。
        rocketMQTemplate.asyncSend(destination, MessageBuilder.withPayload(message).build(), sendCallback);
        // 方法二。
        rocketMQTemplate.asyncSend(destination, message, sendCallback);
        // 以上两种方法都可完成发送,其中方法一是方法二的底层方法。本人习惯用第二种,因为操作方便。
    }
3.单向发送
    /**
     * 单向发送
     */
    private void sendOneWay() {
        // 终点:即消息的键。由topic和tag(可无)通过:连接而成,例topic:tag、topic。
        String destination = "topic:tag";
        // 消息:即消息的值。是要发送的内容,可为任意类型,此处用String。
        String message = "Hello World";
        // 方法一。
        rocketMQTemplate.sendOneWay(destination, MessageBuilder.withPayload(message).build());
        // 方法二。
        rocketMQTemplate.sendOneWay(destination, message);
        // 以上两种方法都可完成发送,其中方法一是方法二的底层方法。本人习惯用第二种,因为操作方便。
    }

四 顺序发送

    /**
     * 顺序发送
     */
    private void orderSend() {

        // 同步顺序发送。
        String destination = "topic:tag";
        String message = "Hello World";
        String key = "key";
        // 方法一。
        SendResult sendResult = rocketMQTemplate.syncSendOrderly(destination, MessageBuilder.withPayload(message).build(), key);
        // 方法二。
        sendResult = rocketMQTemplate.syncSendOrderly(destination, message, key);


        // 异步顺序发送。
        SendCallback sendCallback = new SendCallback() {

            /**
             * 处理成功
             * @param sendResult 发送结果对象
             */
            @Override
            public void onSuccess(SendResult sendResult) {
                // 发送成功时执行逻辑。
            }

            /**
             * 处理成功
             * @param throwable 错误对象
             */
            @Override
            public void onException(Throwable throwable) {
                // 发送失败时执行逻辑。一般是将失败数据入库,采用定时的方式尝试再次发送。
            }

        };
        // 方法一。
        rocketMQTemplate.asyncSendOrderly(destination, MessageBuilder.withPayload(message).build(), key, sendCallback);
        // 方法二。
        rocketMQTemplate.asyncSendOrderly(destination, message, key, sendCallback);


        // 单向顺序发送。
        // 方法一。
        rocketMQTemplate.sendOneWayOrderly(destination, MessageBuilder.withPayload(message).build(), key);
        // 方法二。
        rocketMQTemplate.sendOneWayOrderly(destination, message, key);
    }

五 批量发送

    /**
     * 批量发送
     */
    private void batchSend() {

        // 同步批量发送。
        String destination = "topic:tag";
        String messageOne = "Hello World";
        String messageTwo = "Goodbye  World";
        // 消息列表。
        List<String> messages = new ArrayList<>();
        messages.add(messageOne);
        messages.add(messageTwo);
        SendResult sendResult = rocketMQTemplate.syncSend(destination, messages);


        // 异步批量发送。
        SendCallback sendCallback = new SendCallback() {

            /**
             * 处理成功
             * @param sendResult 发送结果对象
             */
            @Override
            public void onSuccess(SendResult sendResult) {
                // 发送成功时执行逻辑。
            }

            /**
             * 处理成功
             * @param throwable 错误对象
             */
            @Override
            public void onException(Throwable throwable) {
                // 发送失败时执行逻辑。一般是将失败数据入库,采用定时的方式尝试再次发送。
            }

        };
        rocketMQTemplate.asyncSend(destination, messages, sendCallback);

        // 单向发送无批量发送功能。
    }

六 延时发送

    /**
     * 延时发送
     */
    private void scheduleSend() {

        // 同步延时发送。
        String destination = "topic:tag";
        String message = "Hello World";
        String key = "key";
        // 超时时间:超出该时间后会报超时异常。
        long timeout = 3000L;
        // 延时等级:1~18,分别延时1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h。
        int delayLevel = 3;
        // 方法一。
        SendResult sendResult = rocketMQTemplate.syncSend(destination, MessageBuilder.withPayload(message).build(), timeout, delayLevel);


        // 异步延时发送。
        SendCallback sendCallback = new SendCallback() {

            /**
             * 处理成功
             * @param sendResult 发送结果对象
             */
            @Override
            public void onSuccess(SendResult sendResult) {
                // 发送成功时执行逻辑。
            }

            /**
             * 处理成功
             * @param throwable 错误对象
             */
            @Override
            public void onException(Throwable throwable) {
                // 发送失败时执行逻辑。一般是将失败数据入库,采用定时的方式尝试再次发送。
            }

        };
        rocketMQTemplate.asyncSend(destination, MessageBuilder.withPayload(message).build(), sendCallback, timeout, delayLevel);


        // 单向发送无延时发送功能。
    }

七 事务发送及消费

    【rocketmq-spring-boot-starter】依赖目前尚不支持事务发送。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

说淑人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值