SpringBoot从入门到精通教程(三)- RocketMQ集成和场景案例分析

需求背景

RocketMq是一个由阿里巴巴开源的消息中间件,在设计上借鉴了Kafka,其2012年开源,2017年成为Apache顶级项目。

一般MQ适用场景如下:

1. 流量削峰,提升系统高并发处理能力,比如秒杀场景
2. 异步处理,应用解耦,提高系统吞吐量

RocketMQ基础组件:

1. Producer是消息生产者
2. Consumer是消息消费者
3. Topic是消息传递中间者,其中存放的是消息逻辑地址

技术点

主要使用了两个

1. RocketMQTemplate对象(com.zc.smartcity.rocketmq.core.RocketMQTemplate)

2. spring-boot-starter-rocketmq组件

注:第2点,通过maven官方中央仓库https://search.maven.org/,搜索到了几个,我使用了最新日期的,即第一个

案例说明

场景案例分析:

1. 如何与springboot集成
2. 如何建立连接,发送不同消息数据类型
3. 如何订阅,且消费不同消息数据类型
4. 场景案例分析

代码演示

举两个例子

1. 如何与springboot集成

pom.xml文件

<dependency>
  <groupId>com.github.org-hejianhui</groupId>
  <artifactId>spring-boot-starter-rocketmq</artifactId>
  <version>1.0-RELEASE</version>
</dependency>

application.yml文件

spring:
  # mq service
  rocketmq: 
    name-server: localhost:9876
    producer: 
      group: my-mq-group
      send-message-timeout: 86400
      compress-message-body-threshold: 4096
      max-message-size: 4194304
      retry-times-when-send-async-failed: 0
      retry-next-server: true
      retry-times-when-send-failed: 2

注:这些参数含义,其英文名称理解起来应该不难,就不做进一步解释了

2. 如何建立连接,发送不同消息数据类型

package com.md.demo.rest;

import java.math.BigDecimal;
import java.util.Random;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.md.demo.MyTopics;
import com.md.demo.vo.OrderPaidEvent;
import com.zc.smartcity.rocketmq.core.RocketMQTemplate;

/**
 * @author Minbo
 */
@RestController
public class InitRest {

	protected static Logger logger = LoggerFactory.getLogger(InitRest.class);

	@Resource
	private RocketMQTemplate rocketMQTemplate;

	/**
	 * 发送普通文本消息
	 * http://localhost:9090/sendMsgText
	 * @return
	 */
	@RequestMapping("/sendMsgText")
	public String sendMsgText() {
		// 发送普通文本消息
		String msg = "Hello,World,spring-boot2-rocketmq! flag=" + new Random().nextInt(100);
		String destination1 = MyTopics.TOPIC1 + ":" + MyTopics.TAG1;
		rocketMQTemplate.convertAndSend(destination1, msg);
		logger.info("sendMsg success。发送普通文本消息 msg=" + msg);

		return "success for text";
	}

	/**
	 * 发送对象数据消息
	 * http://localhost:9090/sendMsgObj
	 * @return
	 */
	@RequestMapping("/sendMsgObj")
	public String sendMsgObj() {
		// 发送对象数据消息
		OrderPaidEvent order = new OrderPaidEvent("T_001_ID_" + new Random().nextInt(100), new BigDecimal("88.00"));
		String destination2 = MyTopics.TOPIC1 + ":" + MyTopics.TAG2;
		rocketMQTemplate.convertAndSend(destination2, order);
		logger.info("sendMsg success。发送对象消息 order=" + order.toString());

		return "success for obj";
	}

	/*
	 * RocketMQ的最佳实践中推荐:一个应用尽可能用一个Topic,消息子类型用tags来标识,tags可以由应用自由设置。
	 * 在使用rocketMQTemplate发送消息时,通过设置发送方法的destination参数来设置消息的目的地,
	 * destination的格式为topicName:tagName,:前面表示topic的名称,后面表示tags名称。
	 * 
	 * 注意: tags从命名来看像是一个复数,但发送消息时,目的地只能指定一个topic下的一个tag,不能指定多个。
	 */
}

完整源码下载

我的Github源码地址:

https://github.com/hemin1003/spring-boot-study/tree/master/spring-boot2-study/spring-boot2-parent

 

附加说明

使用命令新建Topic

1、安装完rocketmq后(官方安装教程),进入到apache-rocketmq目录
2、使用命令

sh /bin/mqadmin updateTopic -n localhost:9876 -b localhost:10911 -t test-topic-1

3、如图演示

updateTopic命令主要是三个参数:

-n nameserver地址和端口,一般启动broker时要指定
-b broker_ip:broker_port,ip是启动broker机器的ip,默认是10911
-t 新主题名称

问题:注意事项(autoCreateTopicEnable=true)

1、使用默认设置autoCreateTopicEnable=true,这样会导致topic的设置不能规范管理,没有统一的审核等
2、使用默认设置autoCreateTopicEnable=true,还会造成负载均衡失效

所以,一般生产环境中会设置autoCreateTopicEnable=false

设置方式:启动broker时关闭掉,命令如下

nohup sh bin/mqbroker -n localhost:9876 autoCreateTopicEnable=false &

常见错误

1、call timeout 超时异常

org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout] with root cause
org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:635)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1280)
	at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:301)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.syncSend(RocketMQTemplate.java:126)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.syncSend(RocketMQTemplate.java:101)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.syncSend(RocketMQTemplate.java:89)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.doSend(RocketMQTemplate.java:437)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.doSend(RocketMQTemplate.java:28)

解决办法:调大send-message-timeout值(application.yml)

2、No route info of this topic 异常

See http://rocketmq.apache.org/docs/faq/ for further details.; nested exception is org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, test-topic-1
See http://rocketmq.apache.org/docs/faq/ for further details.] with root cause
org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, test-topic-1
See http://rocketmq.apache.org/docs/faq/ for further details.
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:657)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1280)
	at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:301)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.syncSend(RocketMQTemplate.java:126)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.syncSend(RocketMQTemplate.java:101)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.syncSend(RocketMQTemplate.java:89)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.doSend(RocketMQTemplate.java:437)
	at com.zc.smartcity.rocketmq.core.RocketMQTemplate.doSend(RocketMQTemplate.java:28)

解决方法:参考以上《附加说明》的步骤,需要先新建topic后才能发送消息或消费消息。这里不再做进一步解释

其他官方资料

1、RocketMq官方网址

2、RocketMq官方安装详细步骤,和案例演示说明

3、RocketMQ-SpringBoot官方代码Demo

4、RocketMQ-SpringBoot官方代码Demo-中文教程说明

5、RocketMQ控制台-运维管理系统搭建文档

6、RocketMQ-常见问题FAQ

下一章教程

SpringBoot从入门到精通教程(四)- @Scheduled定时器用法和场景案例分析

该系列教程

SpringBoot从入门到精通教程

 

 

------------------------------------------------------

------------------------------------------------------

 

关于我(个人域名)

我的开源项目集Github

 

期望和大家一起学习,共同进步,共勉,O(∩_∩)O谢谢

欢迎交流问题,可加个人QQ 469580884,

或者,加我的群号 751925591,一起探讨交流问题

不讲虚的,只做实干家

Talk is cheap,show me the code

如果觉得内容赞,您可以请我喝杯咖啡:

        

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贺佬湿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值