实战,用案例来说话

前面已经说了JMS和RocketMQ一些概念和安装,下面使用SpringBoot来亲身操作一下.

生产者的操作

  1. SpringBoot项目创建完成,引入依赖是第一步:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.3.0</version>
</dependency>
  1. 创建生产者是第二步,生产者必须依赖于生产组,而且需要指定nameServer
@Component
public class PayProducer { /**
* 生产组,生产者必须在生产组内
*/
private String producerGroup = "pay_group"; /**
* 端口
*/
private String nameServer = "39.106.214.179:9876"; private DefaultMQProducer producer; public PayProducer() {
producer = new DefaultMQProducer(producerGroup);
// 指定nameServer地址,多个地址之间以 ; 隔开
producer.setNamesrvAddr(nameServer);
start();
} public DefaultMQProducer getProducer() {
return producer;
} /**
* 对象在使用之前必须调用一次,并且只能初始化一次
*/
public void start() {
try {
this.producer.start();
} catch (MQClientException e) {
e.printStackTrace();
}
} /**
* 一般在应用上下文,使用上下文监听器,进行关闭
*/
public void shutdown() {
producer.shutdown();
} }
  1. 创建Controller进行测试发送消息,必须要指定topic,消息依赖于主题
@RestController
public class PayController { @Autowired
private PayProducer payProducer; /**
* topic,消息依赖于topic
*/
private static final String topic = "pay_test_topic"; @RequestMapping("/api/v1/pay_cb")
public Object callback(String text) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
// 创建消息 主题 二级分类 消息内容好的字节数组
Message message = new Message(topic, "taga", ("hello rocketMQ " + text).getBytes()); SendResult send = payProducer.getProducer().send(message); System.out.println(send); return new HashMap<>();
} }
  1. 采坑记录

    • 上面完成就可以启动项目了,访问之后报错了:
    MQClientException: No route info of this topic, TopicTest1
    这个的原因就是Broker禁止自动创建Topic且用户没有通过手动方式创建Topic, 或者是broker与Nameserver网络不通
    解决:
    使用手动创建Topic,在RocketMQ控制台的主题中创建就好,最主要的是指定topic name,如下图
    出现创建不了的情况往下看 如果还出现这个问题,请关闭防火墙

    • 这次说下上面可能创建不了的问题,前面说了安装开放安全组,这次就是因为rocketMQ虚拟的端口问题,需要开放10909,也就是说ECS最终开放的端口号: 8080,10911,9876,10909

    • 继续采坑

    org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout
    
    这个问题是阿里云服务器存在多个网卡,rocketMQ会根据当前网卡选择一个IP使用,我们需要制定一个IP:
    路径是: /usr/local/software/rocketmq/distribution/target/apache-rocketmq vim ./conf/broker.conf 添加配置: brokerIP1=公网IP 重新启动:
    nohup sh bin/mqbroker -n localhost:9876 -c ./conf/broker.conf &
    tail -f nohup.out
    • 其他问题
        https://blog.csdn.net/qq_14853889/article/details/81053145
    https://blog.csdn.net/wangmx1993328/article/details/81588217#%E5%BC%82%E5%B8%B8%E8%AF%B4%E6%98%8E
    https://www.jianshu.com/p/bfd6d849f156
    https://blog.csdn.net/wangmx1993328/article/details/81588217

消费者操作

  1. 在前一个项目的基础上,将公共内容提取出来,创建一个JsmConfig的类,来声明公共内容:

    public class JmsConfig {
    
        /**
    * 端口
    */
    public static final String NAME_SERVER = "39.106.214.179:9876"; /**
    * topic,消息依赖于topic
    */
    public static final String TOPIC = "pay_test_topic";
    }
  2. 生产者内容变为

    @Component
    public class PayProducer { /**
    * 生产组,生产者必须在生产组内
    */
    private String producerGroup = "pay_producer_group"; private DefaultMQProducer producer; public PayProducer() {
    producer = new DefaultMQProducer(producerGroup);
    // 指定nameServer地址,多个地址之间以 ; 隔开
    producer.setNamesrvAddr(JmsConfig.NAME_SERVER);
    start();
    } public DefaultMQProducer getProducer() {
    return producer;
    } /**
    * 对象在使用之前必须调用一次,并且只能初始化一次
    */
    public void start() {
    try {
    this.producer.start();
    } catch (MQClientException e) {
    e.printStackTrace();
    }
    } /**
    * 一般在应用上下文,使用上下文监听器,进行关闭
    */
    public void shutdown() {
    producer.shutdown();
    } }
  3. 创建消费者

    @Component
    public class PayConsumer { private DefaultMQPushConsumer consumer; private String consumerGroup = "pay_consumer_group"; public PayConsumer() throws MQClientException {
    consumer = new DefaultMQPushConsumer(consumerGroup);
    consumer.setNamesrvAddr(JmsConfig.NAME_SERVER);
    // 设置消费地点,从最后一个进行消费(其实就是消费策略)
    consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
    // 订阅主题的哪些标签
    consumer.subscribe(JmsConfig.TOPIC, "*");
    // 注册监听器
    consumer.registerMessageListener((MessageListenerConcurrently)
    (msgs, context) -> {
    try {
    // 获取Message
    Message msg = msgs.get(0);
    System.out.printf("%s Receive New Messages: %s %n",
    Thread.currentThread().getName(), new String(msgs.get(0).getBody()));
    String topic = msg.getTopic();
    String body = new String(msg.getBody(), "utf-8");
    // 标签
    String tags = msg.getTags();
    String keys = msg.getKeys();
    System.out.println("topic=" + topic + ", tags=" + tags + ",keys=" + keys + ", msg=" + body);
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    return ConsumeConcurrentlyStatus.RECONSUME_LATER;
    }
    });
    consumer.start();
    System.out.println("Consumer Listener");
    } }
  4. Controller的变化:

    @RestController
    public class PayController { @Autowired
    private PayProducer payProducer; @RequestMapping("/api/v1/pay_cb")
    public Object callback(String text) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
    // 创建消息 主题 二级分类 消息内容好的字节数组
    Message message = new Message(JmsConfig.TOPIC, "taga", ("hello rocketMQ " + text).getBytes()); SendResult send = payProducer.getProducer().send(message); System.out.println(send); return new HashMap<>();
    } }

梳理一下整个流程,生产者存在于生产组,所以生产组很重要,创建生产者需要指定生产组.消费者同理,创建消费者也需要指定消费组. 并且二者都需要指定NameServer. 有了生产者就要发送消息,也就是Message,创建Message需要指定Topic,二级分类和消息体等信息. 那消费者如何获取呢? 无非就是绑定Topic和二级分类就可以,这就是整个流程. 中间少说了消息的存放,消息是在broker中,这个相当于仓库,所以就是生产者生产消息到Broker,Consumer从Broker中获取消息进行消费.

SpringBoot集成RocketMQ的更多相关文章

  1. SpringBoot - 集成RocketMQ实现延迟消息队列

    目录 前言 环境 具体实现 前言 RocketMQ是阿里巴巴在2012年开源的分布式消息中间件,记录下SpringBoot整合RocketMQ的方式,RocketMQ的安装可以查看:Windows下安 ...

  2. springboot之RocketMq实现

    环境:win10 1.下载安装包 http://mirrors.tuna.tsinghua.edu.cn/apache/rocketmq/4.4.0/rocketmq-all-4.4.0-bin-re ...

  3. 【springBoot】springBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...

  4. SpringBoot集成security

    本文就SpringBoot集成Security的使用步骤做出解释说明.

  5. springboot集成Actuator

    Actuator监控端点,主要用来监控与管理. 原生端点主要分为三大类:应用配置类.度量指标类.操作控制类. 应用配置类:获取应用程序中加载的配置.环境变量.自动化配置报告等与SpringBoot应用 ...

  6. SpringBoot集成Shiro并用MongoDB做Session存储

    之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mong ...

  7. SpringBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...

  8. springboot集成mybatis(二)

    上篇文章<springboot集成mybatis(一)>介绍了SpringBoot集成MyBatis注解版.本文还是使用上篇中的案例,咱们换个姿势来一遍^_^ 二.MyBatis配置版(X ...

  9. springboot集成mybatis(一)

    MyBatis简介 MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyB ...

随机推荐

  1. 基于MongodbDB的用户认证-运维笔记

    MongoDB默认是不认证的,默认没有账号,只要能连接上服务就可以对数据库进行各种操作,MongoDB认为安全最好的方法就是在一个可信的环境中运行它,保证之后可信的机器才能访问它,可能这些对一些要求高 ...

  2. redis持久化策略梳理及主从环境下的策略调整记录

    redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化.可以不定期的通过异步方式保存到磁盘上(即“半持久化模式”):也可以把每一次数据变化都写入到一个A ...

  3. nginx的web缓存服务环境部署记录

    web缓存位于内容源Web服务器和客户端之间,当用户访问一个URL时,Web缓存服务器会去后端Web源服务器取回要输出的内容,然后,当下一个请求到来时,如果访问的是相同的URL,Web缓存服务器直接输 ...

  4. oracle数据恢复方法

    https://www.cnblogs.com/hqbhonker/p/3977200.html

  5. 使用Eclipse可以方便的统计工程或文件的代码行数,

    使用Eclipse可以方便的统计工程或文件的代码行数,方法如下: 1.点击要统计的项目或许文件夹,在菜单栏点击Search,然后点击File... 2.选中正则表达式(Regular expressi ...

  6. Microsoft Orleans构建高并发、分布式的大型应用程序框架

    Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...

  7. Beta阶段敏捷冲刺四

    一.举行站立式会议 1.当天站立式会议照片一张 2.团队成员报告 林楚虹 (1) 昨天已完成的工作:导入到数据表 (2) 今天计划完成的工作:排行榜功能 (3) 工作中遇到的困难:转为csv文件时音标 ...

  8. js十大排序算法:冒泡排序

    排序算法说明: (1)对于评述算法优劣术语的说明 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面:不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面: 内排序:所有排 ...

  9. Fuck me 忘记改REDO 造成复制用户超级慢

    . 一个用户的测试环境, 想着复制用户进行功能和单点性能测试. 但是用户数据量较大,见图 2. 发现在测试环境里面复制一个用户 大概耗时2小时20min的时间, 测试虚拟机的配置: 最开始注意到awr ...

  10. python学习笔记七——字典

    4.3 字典结构 字典是Python中重要的数据类型,字典的由“键-值”对组成的集合,字典中的“值”通过“键”来引用. 4.3.1 字典的创建 字典由一系列的“键-值”(key-value)对组成,“ ...