Springboot整合RocketMQ

参考文章:https://blog.csdn.net/gzmyh/article/details/130222388

前置条件、安装好RocketMQ、RocketMQ仪表盘

第一步、引入依赖

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.2.3</version>
</dependency>

第二步、创建生产者模块

1、配置文件

rocketmq:
  # NameServer
  name-server: 127.0.0.1:9876
  producer:
    # 发送消息超时时间,默认3000
    send-message-timeout: 30000
    # 生产者组
    group: groupTest
    # 发送消息失败重试次数,默认2
    retryTimesWhenSendFailed: 2
    # 异步消息重试此处,默认2
    retryTimesWhenSendAsyncFailed: 2

2、创建RocketMQTemplate

封装了RocketMQ的生产者API,提供了一系列简单易用的方法,用于发送不同类型的消息, 后面的例子都会用到它

我们要新建一个ExtRocketMQTemplate类去继承RocketMQTemplate

import org.apache.rocketmq.spring.annotation.ExtRocketMQTemplateConfiguration;
import org.apache.rocketmq.spring.core.RocketMQTemplate;

@ExtRocketMQTemplateConfiguration(nameServer = "${rocketmq.name-server}")
public class ExtRocketMQTemplate extends RocketMQTemplate {

}

3 普通消息

        普通消息为 Apache RocketMQ 中最基础的消息 , 普通消息一般应用于微服务解耦、事件驱动、数据集成等场景,这些场景大多数要求数据传输通道具有可靠传输的能力,且对消息的处理时机、处理顺序没有特别要求。

3.1 单向消息发送

       指发送消息后,不需要等待Broker的响应,直接返回。这种方式适用于不需要关注消息发送结果的场景,如日志记录、统计信息等。

/**
     * 发送消息后,不需要等待Broker的响应,直接返回。
     * 这种方式适用于不需要关注消息发送结果的场景,如日志记录、统计信息等
     * @return
     */
    @GetMapping("/sendOneWay")
    @ApiOperation(value = "单向发送消息")
    @ApiOperationSupport(order = 1)
    public void sendOneWay() {
        for (int i = 1; i <=3; i++) {
            HeroDTO heroDTO = new HeroDTO();
            heroDTO.setId(IdUtil.fastUUID());
            heroDTO.setName("伽罗"+i);

            Message<String> msgs = MessageBuilder.withPayload(JSON.toJSONString(heroDTO))
                    //设置消息KEYS,一般是数据的唯一ID,主要用于在仪表盘中方便搜索
                    .setHeader("KEYS", "111")
                    .build();

            //给消息打上射手的标签。主题+tag,中间用“:”分隔,主要是用于消息的过滤,比如说在消费的时候,只消费ess标签下的消息
            extRocketMQTemplate.sendOneWay("topicA".concat(":ess"), msgs);

            log.info("单向发送消息" + heroDTO);
        }
    }

3.2 同步发送消息

/**
     * syncSend方法会阻塞当前线程,直到消息发送完成并收到了消息服务器的响应。
     * 如果消息发送成功,syncSend方法会返回一个SendResult对象,包含了消息的发送状态、消息ID等信息。
     * 如果消息发送失败,syncSend方法会抛出一个MessagingException异常。
     * @return
     */
    @GetMapping("/syncSend")
    @ApiOperation(value = "同步发送消息")
    @ApiOperationSupport(order = 2)
    public void syncSend() {
        HeroDTO heroDTO = new HeroDTO();
        heroDTO.setId(IdUtil.fastUUID());
        heroDTO.setName("鲁班");

        Message<String> msgs = MessageBuilder.withPayload(JSON.toJSONString(heroDTO))
                //设置消息KEYS,一般是数据的唯一ID,主要用于在仪表盘中方便搜索
                .setHeader("KEYS", "222")
                .build();

        SendResult sendResult = extRocketMQTemplate.syncSend("topicB".concat(":ess"), msgs);

        log.info(heroDTO.toString());
        log.info(sendResult.toString());
    }

3.3 异步发送消息

/**
     * asyncSend方法不会阻塞当前线程,而是在另一个线程中异步发送消息。
     * 因此,asyncSend方法会立即返回,不会等待消息发送完成。
     * 如果需要等待消息发送完成并处理发送结果,可以使用SendCallback回调接口。
     * @return
     */
    @GetMapping("/asyncSend")
    @ApiOperation(value = "异步发送消息")
    @ApiOperationSupport(order = 3)
    public void asyncSend() {
        HeroDTO heroDTO = new HeroDTO();
        heroDTO.setId("sunshangxiang");
        heroDTO.setName("孙尚香");

        Message<String> msgs = MessageBuilder.withPayload(JSON.toJSONString(heroDTO))
                //设置消息KEYS,一般是数据的唯一ID,主要用于在仪表盘中方便搜索
                .setHeader("KEYS", "333")
                .build();

        extRocketMQTemplate.asyncSend("topicC".concat(":ess"), msgs, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info(sendResult.toString());
            }

            @Override
            public void onException(Throwable e) {
                log.info(e.getMessage());
            }
        });
    }

4 顺序消息

       顺序消息是 Apache RocketMQ 提供的一种高级消息类型,支持消费者按照发送消息的先后顺序获取消息,从而实现业务场景中的顺序处理。 相比其他类型消息,顺序消息在发送、存储和投递的处理过程中,更多强调多条消息间的先后顺序关系。

4.1单向顺序消息

/**
     * 顺序消息是 Apache RocketMQ 提供的一种高级消息类型,
     * 支持消费者按照发送消息的先后顺序获取消息,从而实现业务场景中的顺序处理。
     * 相比其他类型消息,顺序消息在发送、存储和投递的处理过程中,更多强调多条消息间的先后顺序关系。
     */
    @GetMapping("/sendOneWayOrderly")
    @ApiOperation(value = "单向发送顺序消息")
    @ApiOperationSupport(order = 4)
    public void sendOneWayOrderly() {
        for (int i = 1; i <=3; i++) {
            HeroDTO heroDTO = new HeroDTO();
            heroDTO.setId("zhangfei");
            heroDTO.setName("张飞"+i);

            Message<String> msgs = MessageBuilder.withPayload(JSON.toJSONString(heroDTO))
                    //设置消息KEYS,一般是数据的唯一ID,主要用于在仪表盘中方便搜索
                    .setHeader("KEYS", "444")
                    .build();

            //顺序消息比普通消息多一个参数,第三个参数只要唯一就行,比如ID
            extRocketMQTemplate.sendOneWayOrderly("topicD".concat(":tank"), msgs,heroDTO.getId());
        }
    }

4.2同步发送顺序消息

@GetMapping("/syncSendOrderly")
    @ApiOperation(value = "同步发送顺序消息")
    @ApiOperationSupport(order = 5)
    public void syncSendOrderly() {
        for (int i = 1; i <=3; i++) {
            HeroDTO heroDTO = new HeroDTO();
            heroDTO.setId("guanyu");
            heroDTO.setName("关羽"+i);

            Message<String> msgs = MessageBuilder.withPayload(JSON.toJSONString(heroDTO))
                    //设置消息KEYS,一般是数据的唯一ID,主要用于在仪表盘中方便搜索
                    .setHeader("KEYS", "555")
                    .build();
            SendResult sendResult = extRocketMQTemplate.syncSendOrderly("topicE".concat(":tank"), msgs,heroDTO.getId());
            log.info(sendResult.toString());
        }
    }

4.3异步发送顺序消息

经测试,这里并不能保证消息的顺序

/**
     * 异步发送只是多了一个SendCallback参数。注意:异步发送顺序消息并不能严格保证消息的顺序。
     */
    @GetMapping("/asyncSendOrderly")
    @ApiOperation(value = "异步发送顺序消息")
    @ApiOperationSupport(order = 6)
    public void asyncSendOrderly() {
        for (int i = 1; i <=3; i++) {
            HeroDTO heroDTO = new HeroDTO();
            heroDTO.setId("xiangyu");
            heroDTO.setName("项羽"+i);

            Message<String> msgs = MessageBuilder.withPayload(JSON.toJSONString(heroDTO))
                    //设置消息KEYS,一般是数据的唯一ID,主要用于在仪表盘中方便搜索
                    .setHeader("KEYS", "666")
                    .build();

            extRocketMQTemplate.asyncSendOrderly("topicF".concat(":tank"), msgs,heroDTO.getId(), new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    log.info(sendResult.toString());
                }

                @Override
                public void onException(Throwable e) {
                    log.info(e.getMessage());
                }
            });
        }
    }

5 延时消息

        延时消息是 Apache RocketMQ 提供的一种高级消息类型,消息被发送至服务端后,在指定时间后才能被消费者消费。

@GetMapping("/syncSendDelayTimeSeconds")
    @ApiOperation(value = "延时发送消息")
    @ApiOperationSupport(order = 7)
    public void syncSendDelayTimeSeconds() {
        HeroDTO heroDTO = new HeroDTO();
        heroDTO.setId("baiqi");
        heroDTO.setName("白起");

        Message<String> msgs = MessageBuilder.withPayload(JSON.toJSONString(heroDTO))
                //设置消息KEYS,一般是数据的唯一ID,主要用于在仪表盘中方便搜索
                .setHeader("KEYS", "777")
                .build();
        //10秒后才能消费这条消息
        SendResult sendResult = extRocketMQTemplate.syncSendDelayTimeSeconds("topicG".concat(":tank"), msgs, 10L);
        log.info(sendResult.toString());

    }

6 批量发送

@GetMapping("/syncSendBatchMessage")
    @ApiOperation(value = "批量发送消息")
    @ApiOperationSupport(order = 8)
    public void syncSendBatchMessage() {
        List<HeroDTO> heroList = new ArrayList<>();
        HeroDTO h1 = new HeroDTO();
        h1.setId("geya");
        h1.setName("戈娅");
        heroList.add(h1);

        HeroDTO h2 = new HeroDTO();
        h2.setId("direnjie");
        h2.setName("狄仁杰");
        heroList.add(h2);

        List<Message> msgs = new ArrayList<Message>();
        for (HeroDTO hero : heroList){
            Message<String> message = MessageBuilder.withPayload(JSON.toJSONString(hero))
                    .setHeader("KEYS", hero.getId())
                    .build();
            msgs.add(message);
        }

        SendResult sendResult = extRocketMQTemplate.syncSend("topicH".concat(":shooter"), msgs);
        log.info(sendResult.toString());
    }

 第三步、创建消费者

消费者和生产者通常不在一个应用里,消费者的代码很简单,新建一个继承RocketMQListener监听器

配置文件和相关代码

rocketmq:
  # NameServer
  name-server: 127.0.0.1:9876
  # 默认的消息组
  producer:
    group: groupTest
@Component
@RocketMQMessageListener(consumerGroup = "group8", topic = "topicH",consumeMode = ConsumeMode.ORDERLY,selectorExpression = "shooter")
@Slf4j
public class ConsumerListener8 implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
       log.info("Received message : " + message);
    }

}

接下来了解一下@RocketMQMessageListener这个注解

  • topic:主题,指消费者组订阅的消息服务
  • consumerGroup:消费者组,一个组可以有多个消费者,主要的作用是集群模式负载均衡的实现,广播模式的通知的实现
  • consumeModel:控制消费模式,你可以选择并发或有序接收消息
  • messageModel:控制消息模式,广播模式-所有消费者都能接收到信息, 集群模式:无论有多少个消费者,只有一个消费者能够接收到信息,也就是说消息一旦被消费了,其它消费者就不能消费该条消息
  • selectorExpression:选择哪个标签(tag)下的信息,默认是消费该主题下的所有信息

排坑

问题1:MQClientException: No route info of this topic, mytopic

问题描述:我是在window上使用RocketMQ,环境配置,文件配置,MQ启动,一系列操作都成功后,然后在项目中使用MQ的时候报了这个错!!!

答:改变broker启动方式:用命令行启动并指定端口和自动创建Topic。

start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true

问题2:有些消息dashboard看到2条

回答1:重复查询的问题是仪表板的源代码,这可能是5.1.1版本之后的不兼容造成的。建议手动更改源代码:

Org. apache. locketmq. dashboard. service. impl. Message Service Impl # queryFirstMessage Page
Line 271 should read:
Long maxOffset=consumer. searchOffset (messageQueue, query. getEnd()); 

回答2:是的,此回答整理自钉群“群2-Apache RocketMQ 中国开发者钉钉群”

参考:https://developer.aliyun.com/ask/531505

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个用于构建独立的、基于生产的Java应用程序的框架,而RocketMQ是一个开源的分布式消息队列。将Spring Boot整合RocketMQ可以实现在应用程序中使用RocketMQ进行消息的发送和接收。 要在Spring Boot整合RocketMQ,首先需要在pom.xml文件中添加RocketMQ的依赖。可以使用如下代码添加依赖: ```xml <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>${rocketmq.version}</version> </dependency> ``` 其中,`${rocketmq.version}`是RocketMQ的版本号,可以根据实际情况进行设置。接下来,需要在application.yml配置文件中进行相关配置,包括RocketMQ的地址、消费者和生产者的配置等。 在代码中,可以使用`@RocketMQMessageListener`注解来标记RocketMQ的消息监听器,使用`@RocketMQListener`注解来指定监听的消息主题和标签。同时,也可以使用`@Slf4j`注解来引入日志记录器。 然后,可以创建相应的消费者和生产者服务类,分别实现RocketMQ的消费者和生产者接口。消费者服务类需要实现`RocketMQListener`接口,并实现其`onMessage`方法来处理接收到的消息。生产者服务类可以使用RocketMQ的`RocketMQTemplate`类来发送消息。 最后,可以在控制器中调用消费者和生产者的服务类来实现消息的发送和接收。 这样,就完成了Spring BootRocketMQ整合。通过整合,可以方便地在Spring Boot应用程序中使用RocketMQ进行消息的传递和处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [RocketMQ整合SpringBoot](https://blog.csdn.net/weixin_47638656/article/details/113849725)[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^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值