1、RocketMQ简介

1.1 架构图片

1.2 角色分类

  1. Broker

    RocketMQ 的核心,接收 Producer 发过来的消息、处理 Consumer 的消费消息请求、消息的持 久化存储、服务端过滤功能等 。

  2. NameServer

    消息队列中的状态服务器,集群的各个组件通过它来了解全局的信息 。类似微服务中注册中心的服务注册,发现,下线,上线的概念。

    热备份

    NamServer可以部署多个,相互之间独立,其他角色同时向多个NameServer 机器上报状态信息。

    心跳机制

    NameServer 中的 Broker、 Topic等状态信息不会持久存储,都是由各个角色定时上报并存储到内存中,超时不上报的话, NameServer会认为某个机器出故障不可用。

  3. Producer

    消息的生成者,最常用的producer类就是DefaultMQProducer。

  4. Consumer

  • 消息的消费者,常用Consumer类
  • DefaultMQPushConsumer
  • 收到消息后自动调用传入的处理方法来处理,实时性高
  • DefaultMQPullConsumer
  • 用户自主控制 ,灵活性更高。

1.3 通信机制

  1. Broker启动后需要完成一次将自己注册至NameServer的操作;随后每隔30s时间定时向NameServer更新Topic路由信息。
  2. Producer发送消息时候,需要根据消息的Topic从本地缓存的获取路由信息。如果没有则更新路由信息会从NameServer重新拉取,同时Producer会默认每隔30s向NameServer拉取一次路由信息。
  3. Consumer消费消息时候,从NameServer获取的路由信息,并再完成客户端的负载均衡后,监听指定消息队列获取消息并进行消费。

2、实现案例

2.1 项目结构图

  1. <spring-boot.version>2.1.3.RELEASE</spring-boot.version>
  2. <rocketmq.version>4.3.0</rocketmq.version>

2.2 配置文件

  1. rocketmq:
  2. # 生产者配置
  3. producer:
  4. isOnOff: on
  5. # 发送同一类消息的设置为同一个group,保证唯一
  6. groupName: FeePlatGroup
  7. # 服务地址
  8. namesrvAddr: 10.1.1.207:9876
  9. # 消息最大长度 默认1024*4(4M)
  10. maxMessageSize: 4096
  11. # 发送消息超时时间,默认3000
  12. sendMsgTimeout: 3000
  13. # 发送消息失败重试次数,默认2
  14. retryTimesWhenSendFailed: 2
  15. # 消费者配置
  16. consumer:
  17. isOnOff: on
  18. # 官方建议:确保同一组中的每个消费者订阅相同的主题。
  19. groupName: FeePlatGroup
  20. # 服务地址
  21. namesrvAddr: 10.1.1.207:9876
  22. # 接收该 Topic 下所有 Tag
  23. topics: FeePlatTopic~*;
  24. consumeThreadMin: 20
  25. consumeThreadMax: 64
  26. # 设置一次消费消息的条数,默认为1条
  27. consumeMessageBatchMaxSize: 1
  28. # 配置 Group Topic Tag
  29. fee-plat:
  30. fee-plat-group: FeePlatGroup
  31. fee-plat-topic: FeePlatTopic
  32. fee-account-tag: FeeAccountTag

2.3 生产者配置

  1. import org.apache.rocketmq.client.exception.MQClientException;
  2. import org.apache.rocketmq.client.producer.DefaultMQProducer;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. /**
  9. * RocketMQ 生产者配置
  10. */
  11. @Configuration
  12. public class ProducerConfig {
  13. private static final Logger LOG = LoggerFactory.getLogger(ProducerConfig.class) ;
  14. @Value("${rocketmq.producer.groupName}")
  15. private String groupName;
  16. @Value("${rocketmq.producer.namesrvAddr}")
  17. private String namesrvAddr;
  18. @Value("${rocketmq.producer.maxMessageSize}")
  19. private Integer maxMessageSize ;
  20. @Value("${rocketmq.producer.sendMsgTimeout}")
  21. private Integer sendMsgTimeout;
  22. @Value("${rocketmq.producer.retryTimesWhenSendFailed}")
  23. private Integer retryTimesWhenSendFailed;
  24. @Bean
  25. public DefaultMQProducer getRocketMQProducer() {
  26. DefaultMQProducer producer;
  27. producer = new DefaultMQProducer(this.groupName);
  28. producer.setNamesrvAddr(this.namesrvAddr);
  29. //如果需要同一个jvm中不同的producer往不同的mq集群发送消息,需要设置不同的instanceName
  30. if(this.maxMessageSize!=null){
  31. producer.setMaxMessageSize(this.maxMessageSize);
  32. }
  33. if(this.sendMsgTimeout!=null){
  34. producer.setSendMsgTimeout(this.sendMsgTimeout);
  35. }
  36. //如果发送消息失败,设置重试次数,默认为2次
  37. if(this.retryTimesWhenSendFailed!=null){
  38. producer.setRetryTimesWhenSendFailed(this.retryTimesWhenSendFailed);
  39. }
  40. try {
  41. producer.start();
  42. } catch (MQClientException e) {
  43. e.printStackTrace();
  44. }
  45. return producer;
  46. }
  47. }

2.4 消费者配置

  1. import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
  2. import org.apache.rocketmq.client.exception.MQClientException;
  3. import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. import javax.annotation.Resource;
  10. /**
  11. * RocketMQ 消费者配置
  12. */
  13. @Configuration
  14. public class ConsumerConfig {
  15. private static final Logger LOG = LoggerFactory.getLogger(ConsumerConfig.class) ;
  16. @Value("${rocketmq.consumer.namesrvAddr}")
  17. private String namesrvAddr;
  18. @Value("${rocketmq.consumer.groupName}")
  19. private String groupName;
  20. @Value("${rocketmq.consumer.consumeThreadMin}")
  21. private int consumeThreadMin;
  22. @Value("${rocketmq.consumer.consumeThreadMax}")
  23. private int consumeThreadMax;
  24. @Value("${rocketmq.consumer.topics}")
  25. private String topics;
  26. @Value("${rocketmq.consumer.consumeMessageBatchMaxSize}")
  27. private int consumeMessageBatchMaxSize;
  28. @Resource
  29. private RocketMsgListener msgListener;
  30. @Bean
  31. public DefaultMQPushConsumer getRocketMQConsumer(){
  32. DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName);
  33. consumer.setNamesrvAddr(namesrvAddr);
  34. consumer.setConsumeThreadMin(consumeThreadMin);
  35. consumer.setConsumeThreadMax(consumeThreadMax);
  36. consumer.registerMessageListener(msgListener);
  37. consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
  38. consumer.setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize);
  39. try {
  40. String[] topicTagsArr = topics.split(";");
  41. for (String topicTags : topicTagsArr) {
  42. String[] topicTag = topicTags.split("~");
  43. consumer.subscribe(topicTag[0],topicTag[1]);
  44. }
  45. consumer.start();
  46. }catch (MQClientException e){
  47. e.printStackTrace();
  48. }
  49. return consumer;
  50. }
  51. }

2.5 消息监听配置

  1. import com.rocket.queue.service.impl.ParamConfigService;
  2. import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
  3. import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
  4. import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
  5. import org.apache.rocketmq.common.message.MessageExt;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.stereotype.Component;
  9. import org.springframework.util.CollectionUtils;
  10. import javax.annotation.Resource;
  11. import java.util.List;
  12. /**
  13. * 消息消费监听
  14. */
  15. @Component
  16. public class RocketMsgListener implements MessageListenerConcurrently {
  17. private static final Logger LOG = LoggerFactory.getLogger(RocketMsgListener.class) ;
  18. @Resource
  19. private ParamConfigService paramConfigService ;
  20. @Override
  21. public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext context) {
  22. if (CollectionUtils.isEmpty(list)){
  23. return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
  24. }
  25. MessageExt messageExt = list.get(0);
  26. LOG.info("接受到的消息为:"+new String(messageExt.getBody()));
  27. int reConsume = messageExt.getReconsumeTimes();
  28. // 消息已经重试了3次,如果不需要再次消费,则返回成功
  29. if(reConsume ==3){
  30. return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
  31. }
  32. if(messageExt.getTopic().equals(paramConfigService.feePlatTopic)){
  33. String tags = messageExt.getTags() ;
  34. switch (tags){
  35. case "FeeAccountTag":
  36. LOG.info("开户 tag == >>"+tags);
  37. break ;
  38. default:
  39. LOG.info("未匹配到Tag == >>"+tags);
  40. break;
  41. }
  42. }
  43. // 消息消费成功
  44. return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
  45. }
  46. }

2.6 配置参数绑定

  1. import org.springframework.beans.factory.annotation.Value;
  2. import org.springframework.stereotype.Service;
  3. @Service
  4. public class ParamConfigService {
  5. @Value("${fee-plat.fee-plat-group}")
  6. public String feePlatGroup ;
  7. @Value("${fee-plat.fee-plat-topic}")
  8. public String feePlatTopic ;
  9. @Value("${fee-plat.fee-account-tag}")
  10. public String feeAccountTag ;
  11. }

2.7 消息发送测试

  1. import com.rocket.queue.service.FeePlatMqService;
  2. import org.apache.rocketmq.client.producer.DefaultMQProducer;
  3. import org.apache.rocketmq.client.producer.SendResult;
  4. import org.apache.rocketmq.common.message.Message;
  5. import org.springframework.stereotype.Service;
  6. import javax.annotation.Resource;
  7. @Service
  8. public class FeePlatMqServiceImpl implements FeePlatMqService {
  9. @Resource
  10. private DefaultMQProducer defaultMQProducer;
  11. @Resource
  12. private ParamConfigService paramConfigService ;
  13. @Override
  14. public SendResult openAccountMsg(String msgInfo) {
  15. // 可以不使用Config中的Group
  16. defaultMQProducer.setProducerGroup(paramConfigService.feePlatGroup);
  17. SendResult sendResult = null;
  18. try {
  19. Message sendMsg = new Message(paramConfigService.feePlatTopic,
  20. paramConfigService.feeAccountTag,
  21. "fee_open_account_key", msgInfo.getBytes());
  22. sendResult = defaultMQProducer.send(sendMsg);
  23. } catch (Exception e) {
  24. e.printStackTrace();
  25. }
  26. return sendResult ;
  27. }
  28. }

(四)整合 RocketMQ ,实现请求异步处理的更多相关文章

  1. SpringBoot2.0 整合 RocketMQ ,实现请求异步处理

    一.RocketMQ 1.架构图片 2.角色分类 (1).Broker RocketMQ 的核心,接收 Producer 发过来的消息.处理 Consumer 的消费消息请求.消息的持 久化存储.服务 ...

  2. Django中Celery http请求异步处理(四)

    Django中Celery http请求异步处理 本章延续celery之前的系列 1.settings配置 2.编写task jib_update_task任务为更新salt jid数据 3.url设 ...

  3. spring-boot-route(十五)整合RocketMQ

    RocketMQ简介 RocketMQ是阿里巴巴开源的消息中间件.目前已经贡献给Apache软件基金会,成为Apache的顶级项目. rocketMQ基本概念 1. Producer Group 生产 ...

  4. ASP模拟POST请求异步提交数据的方法

    这篇文章主要介绍了ASP模拟POST请求异步提交数据的方法,本文使用MSXML2.SERVERXMLHTTP.3.0实现POST请求,需要的朋友可以参考下 有时需要获取远程网站的某些信息,而服务器又限 ...

  5. spring boot / cloud (四) 自定义线程池以及异步处理@Async

    spring boot / cloud (四) 自定义线程池以及异步处理@Async 前言 什么是线程池? 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线 ...

  6. Redis源码阅读(四)集群-请求分配

    Redis源码阅读(四)集群-请求分配 集群搭建好之后,用户发送的命令请求可以被分配到不同的节点去处理.那Redis对命令请求分配的依据是什么?如果节点数量有变动,命令又是如何重新分配的,重分配的过程 ...

  7. [转载]在服务器端判断request来自Ajax请求(异步)还是传统请求(同步),x-requested-with XMLHttpRequest

    在服务器端判断request来自Ajax请求(异步)还是传统请求(同步) 在服务器端判断request来自Ajax请求(异步)还是传统请求(同步):  两种请求在请求的Header不同,Ajax 异步 ...

  8. SpringBoot(17)---SpringBoot整合RocketMQ

    SpringBoot整合RocketMQ 上篇博客讲解了服务器集群部署RocketMQ 博客地址:RocketMQ(2)---Docker部署RocketMQ集群 这篇在上篇搭建好的基础上,将Spri ...

  9. 【WePY小程序框架实战四】-使用async&await异步请求数据

    [WePY小程序框架实战一]-创建项目 [WePY小程序框架实战二]-页面结构 [WePY小程序框架实战三]-组件传值 async await 是对promise的近一步优化,既解决了promise链 ...

随机推荐

  1. 基于ESP32的智能家居管理系统的设计与实现

    基于ESP32的智能家居管理系统的设计与实现 ESP32的智能家居管理系统访问链接: https://www.cnblogs.com/easyidea/p/13101165.html 一.需求分析 1 ...

  2. Maven的工程类型有哪些?

    POM工程:POM工程是逻辑工程.用在父级工程或聚合工程中.用来做jar包的版本控制. JAR工程:将会打包成jar用作jar包使用.即常见的本地工程 - Java Project. WAR工程:将会 ...

  3. 当Thymeleaf遇到向js中传值的操作

    在使用Thymeleaf的时候.关于一些点击操作非常头疼.往往需要向JS里面传递各种东西. 然而,在用Thymeleaf的时候.js操作需要拼接语句.但是又不好拼接. 关于一些操作,一般也是在表格中. ...

  4. Mapreduce实例--二次排序

    前言部分: 在Map阶段,使用job.setInputFormatClass定义的InputFormat将输入的数据集分割成小数据块splites,同时InputFormat提供一个RecordRed ...

  5. LeapMotion控制器 java语言开发笔记--(LeapMotion控制器简介)

    (1)LeapMotion系统识别和追踪手,手指,以及根手指类似的工具,这个设备运行在一个极小的范围,这个范围拥有个高精度,高跟踪频率可以记录离散的点,手势,和动作. (2)LeapMotion控制器 ...

  6. Servlet[JAX-RS Servlet]的Servlet.init()引发异常

    代码环境 Eclipse2017 : 问题出现: 在测试Hello servlet时发生 org.apache.catalina.core.ApplicationContext log严重: Serv ...

  7. DEDECMS自动编号(序号)autoindex属性(转)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 让织梦dedecms autoindex,itemindex 从0到1开始的办法! 1 2 3 [field:global name=autoin ...

  8. 域名解析 看Cname 信息

    CMD 命令: nslookup -q=cname www.yuzhentan.com

  9. Java并发编程实战(3)- 互斥锁

    我们在这篇文章中主要讨论如何使用互斥锁来解决并发编程中的原子性问题. 目录 概述 互斥锁模型 互斥锁简易模型 互斥锁改进模型 Java世界中的互斥锁 synchronized中的锁和锁对象 synch ...

  10. Lambda获取类属性的名字

    using System; using System.ComponentModel; using System.Linq.Expressions; using System.Reflection; p ...