RocketMQ踩坑记
一、前言
现在的主流消息队列基本都是kafka、RabbitMQ和RocketMQ,只有了解各自的优缺点才能在不同的场景选择合适的MQ,对比图如下:

本篇文章主要介绍我自己在跑官方demo时遇到的一些坑(基于4.3版本),建议先看看RocketMQ的理论知识。
Apache 上开源官方地址:https://rocketmq.apache.org/
GitHub 托管地址:https://github.com/apache/rocketmq
阿里官方的介绍文档:http://jm.taobao.org/2017/01/12/rocketmq-quick-start-in-10-minutes/
Apache 官方提供的 4.3.0 版本的 “快速入门” 文档:https://rocketmq.apache.org/docs/quick-start/
二、安装
安装过程可以参考官方的快速入门文档,这时可能会遇见第一个坑。
坑一:启动broker失败,查看日志nohup.out 显示内存不足
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000005c0000000, 8589934592, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /usr/local/rocketmq-all-4.3.0/distribution/target/apache-rocketmq/hs_err_pid7209.lo
这是因为 apache-rocketmq/bin 目录下启动 nameserv 与 broker 的 runbroker.sh 和 runserver.sh 文件中默认分配的内存太大,而系统实际内存却太小导致启动失败。解决办法就是修改runbroker.sh 和 runserver.sh里的内存配置,调小一些即可。


三、运行官方示例
这时候在服务器启动好namesrv和broker,你以为建个项目复制好代码就万事大吉了?

坑二:No route info of this topic
运行OnewayProducer的main方法控制台可能报如下错误:
org.apache.rocketmq.client.exception.MQClientException: No route info of this topic
网上的解决方案有好几种,主要如下:
1.没有创建topic
原因归于我们没有创建topic,要把启动broker的命令改为nohup sh bin/mqbroker -n localhost:9876 autoCreateTopicEnable=true &
默认情况下 broker会自动创建话题,所以这个完全是没用的。
2.防火墙问题
如果真是防火墙问题,那报错信息一定连接失败什么的,当时我也以为是这个问题但是发现防火墙已经关闭了。
3.pom文件的jar问题
pom文件上rocketmq-client的版本要与 /usr/local/rocketmq-all-4.3.2/distribution/target/apache-rocketmq/lib目录下的jar包版本一致。当时项目pom.xml上的版本是4.3,RocketMQ上的是rocketmq-client-4.3.2.jar,后来将依赖改为4.3.2就好。
4.broker未启动完毕
这是我发现的一种情况,broker启动是需要时间的,日志显示启动成功后再运行代码。
坑三:org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <172.19.0.1:10909> failed
再次运行OnewayProducer会发现错误又变了!
Exception in thread "main" org.apache.rocketmq.client.exception.MQClientException: Send [1] times, still failed, cost [4190]ms, Topic: TopicTest, BrokersSent: [bogon]
See http://rocketmq.apache.org/docs/faq/ for further details.
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:610)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendOneway(DefaultMQProducerImpl.java:905)
at org.apache.rocketmq.client.producer.DefaultMQProducer.sendOneway(DefaultMQProducer.java:285)
at cn.sp.simple.OnewayProducer.main(OnewayProducer.java:21)
Caused by: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <172.19.0.1:10909> failed
at org.apache.rocketmq.remoting.netty.NettyRemotingClient.invokeOneway(NettyRemotingClient.java:561)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:324)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:294)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendKernelImpl(DefaultMQProducerImpl.java:785)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:529)
... 3 more
重点在于connect to <172.19.0.1:10909> failed这里的ip地址并不是我本地虚拟机的ip地址,我们需要手动设置broker的ip地址。
#进入rocketmq根目录
cd /usr/local/rocketmq-all-4.3.2/distribution/target/apache-rocketmq
#编写配置文件,并写好配置
echo "brokerIP1=10.2.x.x" > broker.properties
#启动 mqnamesrv
nohup sh bin/mqnamesrv &
#重点:mrbroker 启动时通过 -c 加载配置文件
nohup sh bin/mqbroker -n localhost:9876 -c /usr/local/rocketmq-all-4.3.2/distribution/target/apache-rocketmq/broker.properties &
这时可以正常的生产消息和消费了,但是当我运行异步生产消息的AsyncProducer时又开始报错了!
坑四:官方示例AsyncProducer代码错误

问题的原因是主线程提前关闭,导致异步线程受到影响,所以可以用CountDownLatch来解决,修改后代码如下:
public class AsyncProducer {
public static void main(String[] args) throws Exception {
//Instantiate with a producer group name.
DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
// Specify name server addresses.
producer.setNamesrvAddr("192.168.75.132:9876");
//Launch the instance.
producer.start();
producer.setRetryTimesWhenSendAsyncFailed(0);
int messageCount = 100;
final CountDownLatch countDownLatch = new CountDownLatch(messageCount);
for (int i = 0; i < messageCount; i++) {
final int index = i;
//Create a message instance, specifying topic, tag and message body.
Message msg = new Message("TopicTest",
"TagA",
"OrderID188",
"Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
countDownLatch.countDown();
System.out.printf("%-10d OK %s %n", index,
sendResult.getMsgId());
}
@Override
public void onException(Throwable e) {
countDownLatch.countDown();
System.out.printf("%-10d Exception %s %n", index, e);
e.printStackTrace();
}
});
}
countDownLatch.await();
//Shut down once the producer instance is not longer in use.
producer.shutdown();
}
}
重新运行该类,发现问题终于解决了。

补充一下RocketMQ可视化控制台的搭建步骤
- 下载源代码,github地址为:https://github.com/apache/rocketmq-externals
- 进入目录rocketmq-console,运行命令 mvn clean package -DskipTests=true得到jar包文件rocketmq-console-ng-1.0.1.jar
- 上传rocketmq-console-ng-1.0.1.jar,使用nohup命令启动即可。
- 游览器访问http://ip:8080即可看到web管理界面,如下图。

四、总结
原本以为就搭个环境跑个demo很快就能完成,没想到遇到了这么多坑,不过也收获很多。
参考资料:
https://blog.csdn.net/wangmx1993328/article/details/81536168
https://my.oschina.net/u/3476125/blog/897429
https://blog.csdn.net/jessDL/article/details/86646086
RocketMQ踩坑记的更多相关文章
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- 【踩坑记】从HybridApp到ReactNative
前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...
- Spark踩坑记——共享变量
[TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
- djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记
情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...
- HttpWebRequest 改为 HttpClient 踩坑记-请求头设置
HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...
- vue踩坑记
vue踩坑记 易错点 语法好难啊qwq 不要把'data'写成'date' 在v-html/v-bind中使用vue变量时不需要加变量名 在非vue事件中使用vue中变量时需要加变量名 正确 < ...
- 【bug记录】OS Lab4 踩坑记
OS Lab4 踩坑记 Lab4在之前Lab3的基础上,增加了系统调用,难度增加了很多.而且加上注释不详细,开玩笑的指导书,自己做起来困难较大.也遇到了大大小小的bug,调试了一整天. 本文记录笔者在 ...
随机推荐
- 单调栈模板 POJ3250
上次二分st表大法失败以后的又一次尝试233333 封装,封装,封装!!!!!! #include <bits/stdc++.h> using namespace std; #define ...
- 第15.40节、PyQt(Python+Qt)实战:moviepy实现MP4视频转gif动图的工具
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 在写<第15.39节.splitDockWidget和 ...
- pytorch 损失函数(nn.BCELoss 和 nn.CrossEntropyLoss)(思考多标签分类问题)
一.BCELoss 二分类损失函数 输入维度为(n, ), 输出维度为(n, ) 如果说要预测二分类值为1的概率,则建议用该函数! 输入比如是3维,则每一个应该是在0--1区间内(随意通常配合sigm ...
- Flutter开发实战笔记
下载 https://flutter.cn/docs/get-started/install/macos#get-sdk 配置环境变量 export PATH="$PATH:[PATH_TO ...
- js setTimeout运行机制
在开始之前先看个面试例子 为什么会是0 1 2 2,而不是 0 0 1 1 再来看个例子 输出结果是4个undefined,为何不是1,2,3,4? 这是为什么呢,这是因为setTimeout是异步的 ...
- 笔记-[APIO2010]特别行动队
笔记-[APIO2010]特别行动队 [APIO2010]特别行动队 \(f_i\) 表示将 \((j+1,j+2,\dots,i)\) 分为一组,已解决 \(i\) 之前的士兵的最小代价. \(a& ...
- 纯css 实现文本换行
业务场景:dialog中嵌套的表单,实现信息展示,由于存储路径过长并且在一行显示,导致多出的文字出现在弹出框外面了,页面极丑,所以需要将存储路径实现自动换行. 技术点:<p style=&quo ...
- sqli-labs less32-37(宽字节注入)
less-32 Bypass addslashes() less-33 Bypass addslashes() less-34 Bypass Add SLASHES less-35 addslashe ...
- Spring Boot 的2020最后一击:2.4.1、2.3.7、2.2.12 发布
近日,Spring Boot官方发布了本年度最后一次版本更新,主要针对目前维护的三个版本: 2.4.x:第一个bug修复版本 2.4.1 2.3.x:常规维护版本 2.3.7 2.2.x:常规维护版本 ...
- Day5 - 02 定义函数
定义函数 Python中定义函数要使用def语句. 依次写出函数名.括号.括号中的参数和冒号,在缩进块中编写函数体,通过return语句返回函数返回值.如: ...