本文源码: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 ,实现请求异步处理的更多相关文章

  1. (四)整合 RocketMQ ,实现请求异步处理

    整合 RocketMQ ,实现请求异步处理 1.RocketMQ简介 1.1 架构图片 1.2 角色分类 1.3 通信机制 2.实现案例 2.1 项目结构图 2.2 配置文件 2.3 生产者配置 2. ...

  2. SpringBoot2.0 整合 Swagger2 ,构建接口管理界面

    一.Swagger2简介 1.Swagger2优点 整合到Spring Boot中,构建强大RESTful API文档.省去接口文档管理工作,修改代码,自动更新,Swagger2也提供了强大的页面测试 ...

  3. SpringBoot2.0 整合 Dubbo框架 ,实现RPC服务远程调用

    一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层 ...

  4. springboot2.0整合logback日志(详细)

    <div class="post"> <h1 class="postTitle"> springboot2.0整合logback日志(详 ...

  5. 第二篇:SpringBoot2.0整合ActiveMQ

    本篇开始将具体介绍SpringBoot如何整合其它项目. 如何创建SpringBoot项目 访问https://start.spring.io/. 依次选择构建工具Maven Project.语言ja ...

  6. SpringBoot2.0 整合 QuartJob ,实现定时器实时管理

    一.QuartJob简介 1.一句话描述 Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大. 2.核心API (1).Scheduler 代表一个 Quartz 的独立运行容 ...

  7. SpringBoot2.0 整合 Redis集群 ,实现消息队列场景

    本文源码:GitHub·点这里 || GitEE·点这里 一.Redis集群简介 1.RedisCluster概念 Redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的 ...

  8. SpringBoot2.0应用(三):SpringBoot2.0整合RabbitMQ

    如何整合RabbitMQ 1.添加spring-boot-starter-amqp <dependency> <groupId>org.springframework.boot ...

  9. SpringBoot2.0整合fastjson的正确姿势

            SpringBoot2.0如何集成fastjson?在网上查了一堆资料,但是各文章的说法不一,有些还是错的,可能只是简单测试一下就认为ok了,最后有没生效都不知道.恰逢公司项目需要将J ...

随机推荐

  1. SAM4E单片机之旅——2、LED闪烁之轮询定时器

    之前我们使用空循环,达到了延迟的目的,但是这样子的延迟比较不精确.现在就使用实时定时器(RTT)来进行更为精确的计时.RTT虽然不是特别通用,在某些单片机上可能没有,但它较为简单. RTT内部有一个计 ...

  2. EasyPusher安卓Android手机直播推送之RTSP流媒体协议流程

    EasyPusher移动端推送同我们平时用的RTSP直播推送流程一样,都是采用标准RTSP/RTP推送流程:ANNOUNCE->SETUP->PLAY->RTP/RTCP->T ...

  3. c++通用写文件调试代码

    #include <stdio.h>#include <sstream>#include <iostream> std::stringstream strs;str ...

  4. parameters arguments 形式参数 实际参数

    parameter和argument的区别 – 笑遍世界 http://smilejay.com/2011/11/parameter_argument/ https://en.wikipedia.or ...

  5. MongoDB 学习五:索引

    这章我们介绍MongoDB的索引,用来优化查询. 索引介绍 数据库索引有些类似书的目录. 一个查询如果没有使用索引被称为表扫描,意思是它必须像阅读整本书那样去获取一个查询结果.一般来说,我们应尽量避免 ...

  6. SpringBoot-(8)-配置MySQL数据库链接,配置数据坚挺拦截,创建默认数据表

    一,链接mysql数据库 # 数据源基本配置 spring.datasource.username=root spring.datasource.password=123456 spring.data ...

  7. Oracle序列更新为主键最大值

    我们在使用 Oracle 数据库的时候,有时候会选择使用自增序列作为主键.但是在开发过程中往往会遇到一些不规范的操作,导致表的主键值不是使用序列插入的.这样在数据移植的时候就会出现各种各样的问题.当然 ...

  8. Backbone vs AngularJS

    首先 Backbone 没有 AngularJS 那么容易上手. 而且作者并没有想让Backbone草根化的意思. Backbone 比喻成战斗机. 看上去更像是真正的MVC框架, model-vie ...

  9. codeforces 701A A. Cards(水题)

    题目链接: A. Cards 题意: 问两个数的和相同,怎么组合; AC代码: #include <iostream> #include <cstdio> #include & ...

  10. 「NOIP2002」「Codevs1099」 字串变换(BFS

    1099 字串变换 2002年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold   题目描述 Description 已知有两个字串 $A$, ...