SpringBoot2.0 整合 RocketMQ ,实现请求异步处理
本文源码:GitHub·点这里 || GitEE·点这里
一、RocketMQ
1、架构图片

2、角色分类
(1)、Broker
RocketMQ 的核心,接收 Producer 发过来的消息、处理 Consumer 的消费消息请求、消息的持 久化存储、服务端过滤功能等 。
(2)、NameServer
消息队列中的状态服务器,集群的各个组件通过它来了解全局的信息 。类似微服务中注册中心的服务注册,发现,下线,上线的概念。
热备份:
NamServer可以部署多个,相互之间独立,其他角色同时向多个NameServer 机器上报状态信息。
心跳机制:
NameServer 中的 Broker、 Topic等状态信息不会持久存储,都是由各个角色定时上报并存储到内存中,超时不上报的话, NameServer会认为某个机器出故障不可用。
(3)、Producer
消息的生成者,最常用的producer类就是DefaultMQProducer。
(4)、Consumer
消息的消费者,常用Consumer类
DefaultMQPushConsumer
收到消息后自动调用传入的处理方法来处理,实时性高
DefaultMQPullConsumer
用户自主控制 ,灵活性更高。
3、通信机制
(1)、Broker启动后需要完成一次将自己注册至NameServer的操作;随后每隔30s时间定时向NameServer更新Topic路由信息。
(2)、Producer发送消息时候,需要根据消息的Topic从本地缓存的获取路由信息。如果没有则更新路由信息会从NameServer重新拉取,同时Producer会默认每隔30s向NameServer拉取一次路由信息。
(3)、Consumer消费消息时候,从NameServer获取的路由信息,并再完成客户端的负载均衡后,监听指定消息队列获取消息并进行消费。
二、代码实现案例
1、项目结构图

版本描述
<spring-boot.version>2.1.3.RELEASE</spring-boot.version>
<rocketmq.version>4.3.0</rocketmq.version>
2、配置文件
rocketmq:
  # 生产者配置
  producer:
    isOnOff: on
    # 发送同一类消息的设置为同一个group,保证唯一
    groupName: CicadaGroup
    # 服务地址
    namesrvAddr: 127.0.0.1:9876
    # 消息最大长度 默认1024*4(4M)
    maxMessageSize: 4096
    # 发送消息超时时间,默认3000
    sendMsgTimeout: 3000
    # 发送消息失败重试次数,默认2
    retryTimesWhenSendFailed: 2
  # 消费者配置
  consumer:
    isOnOff: on
    # 官方建议:确保同一组中的每个消费者订阅相同的主题。
    groupName: CicadaGroup
    # 服务地址
    namesrvAddr: 127.0.0.1:9876
    # 接收该 Topic 下所有 Tag
    topics: CicadaTopic~*;
    consumeThreadMin: 20
    consumeThreadMax: 64
    # 设置一次消费消息的条数,默认为1条
    consumeMessageBatchMaxSize: 1
# 配置 Group  Topic  Tag
rocket:
  group: rocketGroup
  topic: rocketTopic
  tag: rocketTag
3、生产者配置
/**
 * RocketMQ 生产者配置
 */
@Configuration
public class ProducerConfig {
    private static final Logger LOG = LoggerFactory.getLogger(ProducerConfig.class) ;
    @Value("${rocketmq.producer.groupName}")
    private String groupName;
    @Value("${rocketmq.producer.namesrvAddr}")
    private String namesrvAddr;
    @Value("${rocketmq.producer.maxMessageSize}")
    private Integer maxMessageSize ;
    @Value("${rocketmq.producer.sendMsgTimeout}")
    private Integer sendMsgTimeout;
    @Value("${rocketmq.producer.retryTimesWhenSendFailed}")
    private Integer retryTimesWhenSendFailed;
    @Bean
    public DefaultMQProducer getRocketMQProducer() {
        DefaultMQProducer producer;
        producer = new DefaultMQProducer(this.groupName);
        producer.setNamesrvAddr(this.namesrvAddr);
        //如果需要同一个jvm中不同的producer往不同的mq集群发送消息,需要设置不同的instanceName
        if(this.maxMessageSize!=null){
            producer.setMaxMessageSize(this.maxMessageSize);
        }
        if(this.sendMsgTimeout!=null){
            producer.setSendMsgTimeout(this.sendMsgTimeout);
        }
        //如果发送消息失败,设置重试次数,默认为2次
        if(this.retryTimesWhenSendFailed!=null){
            producer.setRetryTimesWhenSendFailed(this.retryTimesWhenSendFailed);
        }
        try {
            producer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
        return producer;
    }
}
4、消费者配置
/**
 * RocketMQ 消费者配置
 */
@Configuration
public class ConsumerConfig {
    private static final Logger LOG = LoggerFactory.getLogger(ConsumerConfig.class) ;
    @Value("${rocketmq.consumer.namesrvAddr}")
    private String namesrvAddr;
    @Value("${rocketmq.consumer.groupName}")
    private String groupName;
    @Value("${rocketmq.consumer.consumeThreadMin}")
    private int consumeThreadMin;
    @Value("${rocketmq.consumer.consumeThreadMax}")
    private int consumeThreadMax;
    @Value("${rocketmq.consumer.topics}")
    private String topics;
    @Value("${rocketmq.consumer.consumeMessageBatchMaxSize}")
    private int consumeMessageBatchMaxSize;
    @Resource
    private RocketMsgListener msgListener;
    @Bean
    public DefaultMQPushConsumer getRocketMQConsumer(){
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName);
        consumer.setNamesrvAddr(namesrvAddr);
        consumer.setConsumeThreadMin(consumeThreadMin);
        consumer.setConsumeThreadMax(consumeThreadMax);
        consumer.registerMessageListener(msgListener);
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        consumer.setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize);
        try {
            String[] topicTagsArr = topics.split(";");
            for (String topicTags : topicTagsArr) {
                String[] topicTag = topicTags.split("~");
                consumer.subscribe(topicTag[0],topicTag[1]);
            }
            consumer.start();
        }catch (MQClientException e){
            e.printStackTrace();
        }
        return consumer;
    }
}
5、消息监听配置
/**
 * 消息消费监听
 */
@Component
public class RocketMsgListener implements MessageListenerConcurrently {
    private static final Logger LOG = LoggerFactory.getLogger(RocketMsgListener.class) ;
    @Resource
    private ParamConfigService paramConfigService ;
    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext context) {
        if (CollectionUtils.isEmpty(list)){
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
        MessageExt messageExt = list.get(0);
        LOG.info("接受到的消息为:"+new String(messageExt.getBody()));
        int reConsume = messageExt.getReconsumeTimes();
        // 消息已经重试了3次,如果不需要再次消费,则返回成功
        if(reConsume ==3){
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
        if(messageExt.getTopic().equals(paramConfigService.rocketTopic)){
            String tags = messageExt.getTags() ;
            switch (tags){
                case "rocketTag":
                    LOG.info("开户 tag == >>"+tags);
                    break ;
                default:
                    LOG.info("未匹配到Tag == >>"+tags);
                    break;
            }
        }
        // 消息消费成功
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
}
6、配置参数绑定
@Service
public class ParamConfigService {
    @Value("${rocket.group}")
    public String rocketGroup ;
    @Value("${rocket.topic}")
    public String rocketTopic ;
    @Value("${rocket.tag}")
    public String rocketTag ;
}
7、消息发送测试
@Service
public class RocketMqServiceImpl implements RocketMqService {
    @Resource
    private DefaultMQProducer defaultMQProducer;
    @Resource
    private ParamConfigService paramConfigService ;
    @Override
    public SendResult openAccountMsg(String msgInfo) {
        // 可以不使用Config中的Group
        defaultMQProducer.setProducerGroup(paramConfigService.rocketGroup);
        SendResult sendResult = null;
        try {
            Message sendMsg = new Message(paramConfigService.rocketTopic,
                                          paramConfigService.rocketTag,
                                         "open_account_key", msgInfo.getBytes());
            sendResult = defaultMQProducer.send(sendMsg);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sendResult ;
    }
}
三、项目源码
GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent

SpringBoot2.0 整合 RocketMQ ,实现请求异步处理的更多相关文章
- (四)整合 RocketMQ ,实现请求异步处理
		整合 RocketMQ ,实现请求异步处理 1.RocketMQ简介 1.1 架构图片 1.2 角色分类 1.3 通信机制 2.实现案例 2.1 项目结构图 2.2 配置文件 2.3 生产者配置 2. ... 
- SpringBoot2.0 整合 Swagger2 ,构建接口管理界面
		一.Swagger2简介 1.Swagger2优点 整合到Spring Boot中,构建强大RESTful API文档.省去接口文档管理工作,修改代码,自动更新,Swagger2也提供了强大的页面测试 ... 
- SpringBoot2.0 整合 Dubbo框架 ,实现RPC服务远程调用
		一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层 ... 
- springboot2.0整合logback日志(详细)
		<div class="post"> <h1 class="postTitle"> springboot2.0整合logback日志(详 ... 
- 第二篇:SpringBoot2.0整合ActiveMQ
		本篇开始将具体介绍SpringBoot如何整合其它项目. 如何创建SpringBoot项目 访问https://start.spring.io/. 依次选择构建工具Maven Project.语言ja ... 
- SpringBoot2.0 整合 QuartJob ,实现定时器实时管理
		一.QuartJob简介 1.一句话描述 Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大. 2.核心API (1).Scheduler 代表一个 Quartz 的独立运行容 ... 
- SpringBoot2.0 整合 Redis集群 ,实现消息队列场景
		本文源码:GitHub·点这里 || GitEE·点这里 一.Redis集群简介 1.RedisCluster概念 Redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的 ... 
- SpringBoot2.0应用(三):SpringBoot2.0整合RabbitMQ
		如何整合RabbitMQ 1.添加spring-boot-starter-amqp <dependency> <groupId>org.springframework.boot ... 
- SpringBoot2.0整合fastjson的正确姿势
		SpringBoot2.0如何集成fastjson?在网上查了一堆资料,但是各文章的说法不一,有些还是错的,可能只是简单测试一下就认为ok了,最后有没生效都不知道.恰逢公司项目需要将J ... 
随机推荐
- live555中fDurationInMicroseconds的计算
			live555中fDurationInMicroseconds表示单个视频或者音频帧所占用的时间间隔,也表示在fDurationInMicroseconds微秒时间后再次向Source进行getNex ... 
- iframe调用父页面js函数 方法 元素
			在一个页面中添加iframe,但是有时需要与父页面进行通信,传递参数. 网上总结有以下方法: 一.iframe标签中 src属性传参 <iframe src="test.jsp?i ... 
- android打包签名,从生成keystore到完成签名
			输入指令并获得结果:(对应自己的java安装目录) 首先,我们需要一个keystore,当然已经有了的话就不用这一步了:cmd下:进入到jdk的bin目录,这样的话,android.keystore文 ... 
- Java,获取文件的Base64字符串,解码Base64字符串还原文件
			在jdk1.8以前,获取文件Base64字符串需要用到第三方库,从1.8开始,Java中引入了Base64相关的类 以下是代码示例 获取文件的Base64编码字符串 import java.io.Fi ... 
- mysql 修改语法格式
			1.修改字段注释格式 alter table {table} modify column {column} {type} comment '{comment}'; 
- src源dst目标
			dst是destination的缩写,表目的 src是source的缩写,表源 
- Zygote进程介绍【转】
			本文转载自:http://blog.csdn.net/yangwen123/article/details/17258023 Zygote进程介绍 在Android系统中,存在不同的服务,这些服务 ... 
- bzoj4486: [Jsoi2015]串分割
			肉丝哥哥钦定好题 话说我的blog现在为什么到处都是肉丝哥哥 先来想一个弱化版,假如能够n整除K怎么做? 把每个数字看成一个字符串,按字典序排名,这个可以后缀数组解决,然后暴力枚举每种情况,O(1)判 ... 
- Python视频教程
			Python这门语言相对学起来是简单点的,尤其对于测试人员来说,如果达到可以写自动化测试脚本的程度的话,学些基础就是可以的.那么在网上也是有很多资源的,各种培训的视频.作为一名过来人(哈哈),或者说是 ... 
- weixin报警脚本
			#!/bin/bash ### script name weixin.sh ### send messages from weixin for zabbix monitor ### jack ### ... 
