目录
在学习使用RocketMQ发送消息时报错ERROR o.a.r.s.core.RocketMQTemplate :695 http-nio-8002-exec-9 syncSend failed. destination:add-bonus, message:GenericMessage [payload=byte[73], headers={contentType=application/json, id=aa9bb1a3-9213-e2ba-41c5-0d829d707ac7, timestamp=1697360504529}], detail exception info: org.apache.rocketmq.client.exception.MQClientException: Send [3] times, still failed, cost [6649]ms, Topic: add-bonus, BrokersSent: [broker-a, broker-a, broker-a] See http://rocketmq.apache.org/docs/faq/ for further details.
1.情景还原
Docker安装RocketMQ
创建namesev
拉取镜像
docker pull rocketmqinc/rocketmq
创建存储路径
mkdir -p /docker/rocketmq/data/namesrv/logs /docker/rocketmq/data/namesrv/store
创建容器
docker run -d \
--restart=always \
--name rmqnamesrv \
-p 9876:9876 \
-v /docker/rocketmq/data/namesrv/logs:/root/logs \
-v /docker/rocketmq/data/namesrv/store:/root/store \
-e "MAX_POSSIBLE_HEAP=100000000" \
rocketmqinc/rocketmq \
sh mqnamesrv
需要注意的是-e “MAX_POSSIBLE_HEAP=100000000” 设置容器的最大堆内存为1G 可以根据服务器具体内存情况进行更改。
创建broker
创建数据存储路径
mkdir -p /docker/rocketmq/data/broker/logs /docker/rocketmq/data/broker/store /docker/rocketmq/conf
创建配置文件
vi /docker/rocketmq/conf/broker.conf
文件内容(有坑打个标记)
# 所属集群名称,如果节点较多可以配置多个
brokerClusterName = DefaultCluster
#broker名称,master和slave使用相同的名称,表明他们的主从关系
brokerName = broker-a
#0表示Master,大于0表示不同的slave
brokerId = 0
#表示几点做消息删除动作,默认是凌晨4点
deleteWhen = 04
#在磁盘上保留消息的时长,单位是小时
fileReservedTime = 48
#有三个值:SYNC_MASTER,ASYNC_MASTER,SLAVE;同步和异步表示Master和Slave之间同步数据的机制;
brokerRole = ASYNC_MASTER
#刷盘策略,取值为:ASYNC_FLUSH,SYNC_FLUSH表示同步刷盘和异步刷盘;SYNC_FLUSH消息写入磁盘后才返回成功状态,ASYNC_FLUSH不需要;
flushDiskType = ASYNC_FLUSH
创建容器
docker run -d \
--restart=always \
--name rmqbroker \
--link rmqnamesrv:namesrv \
-p 10911:10911 \
-p 10909:10909 \
-v /docker/rocketmq/data/broker/logs:/root/logs \
-v /docker/rocketmq/data/broker/store:/root/store \
-v /docker/rocketmq/conf/broker.conf:/opt/rocketmq-4.4.0/conf/broker.conf \
-e "NAMESRV_ADDR=namesrv:9876" \
-e "MAX_POSSIBLE_HEAP=200000000" \
rocketmqinc/rocketmq \
sh mqbroker -c /opt/rocketmq-4.4.0/conf/broker.conf
同样的这里的指定broker服务的最大堆内存为2G,需要根据实际情况修改,我一开始没改,服务器内存就爆掉了,导致其他服务被自动杀掉。
创建rockermq-console服务
拉取镜像
docker pull pangliang/rocketmq-console-ng
创建容器(需要把ip地址填入你机器的ip地址)
docker run -d \
--restart=always \
--name rmqadmin \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=你实际的机器ip地址:9876 \
-Dcom.rocketmq.sendMessageWithVIPChannel=false" \
-p 9999:8080 \
pangliang/rocketmq-console-ng
需要开放服务器防火墙这四个端口
访问服务器ip:9999地址查看控制台信息
可以看到创建的broker信息
此时在springcloud项目中加入依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.3</version>
</dependency>
yml配置文件写RocketMQ 的配置
rocketmq:
name-server: 你搭建服务器的ip:9876
producer:
group: test-group
send-message-timeout: 60000
然后编写你的发送消息的业务相关代码,示例如下
需要注意的是SpringBoot3版本需要在启动类加如下注解否则报错
加入注解
@Import(RocketMQAutoConfiguration.class)
调用接口
报错ERROR o.a.r.s.core.RocketMQTemplate :695 http-nio-8002-exec-9 syncSend failed. destination:add-bonus, message:GenericMessage [payload=byte[73], headers={contentType=application/json, id=aa9bb1a3-9213-e2ba-41c5-0d829d707ac7, timestamp=1697360504529}], detail exception info: org.apache.rocketmq.client.exception.MQClientException: Send [3] times, still failed, cost [6649]ms, Topic: add-bonus, BrokersSent: [broker-a, broker-a, broker-a] See http://rocketmq.apache.org/docs/faq/ for further details.
2.问题解决
研究试了各种方法,然后找到了解决方案。就是我上面标记的broker配置留下的坑,需要进入容器修改配置文件。
进入容器
docker exec -it 你的broker容器id /bin/bash
进入conf文件夹
cd ../conf
使用vi编辑broker.conf文件
vi broker.conf
在末尾加上
amesrvAddr=127.0.0.1:9876
brokerIP1=你的服务器ip地址
此时完整的文件应该是(记得替换brokerIP1为你服务器的ip地址)
# 所属集群名称,如果节点较多可以配置多个
brokerClusterName = DefaultCluster
#broker名称,master和slave使用相同的名称,表明他们的主从关系
brokerName = broker-a
#0表示Master,大于0表示不同的slave
brokerId = 0
#表示几点做消息删除动作,默认是凌晨4点
deleteWhen = 04
#在磁盘上保留消息的时长,单位是小时
fileReservedTime = 48
#有三个值:SYNC_MASTER,ASYNC_MASTER,SLAVE;同步和异步表示Master和Slave之间同步数据的机制;
brokerRole = ASYNC_MASTER
#刷盘策略,取值为:ASYNC_FLUSH,SYNC_FLUSH表示同步刷盘和异步刷盘;SYNC_FLUSH消息写入磁盘后才返回成功状态,ASYNC_FLUSH不需要;
flushDiskType = ASYNC_FLUSH
amesrvAddr=127.0.0.1:9876
brokerIP1=你的服务器ip地址
保存退出重启容器
docker restart broker容器id
再次调用接口发送消息,发现已经成功了