最近在搞项目,重新搞了mysql、redis这些基础环境,因为自己手上有个黑群辉nas 918,所以玩了一下docker,顺利的安装了mysql、redis,但是到rocketMQ的时候,发现网上没有一篇是讲nas上安装的,因为自己也踩了不少坑,所以记录下。
1. docker搜索镜像,安装官方的最新版
2. 容器界面,新增,进行配置
配置一下端口映射,这里要记住,因为后面使用时,都需要填nas的ip+端口号。
之后一直下一步就行。有人习惯做文件夹映射,这个看个人喜好,我觉得用默认的就挺好。安装完成后,点击启动,进入终端机。
rocketmq和redis等不同,需要在终端机执行对应的命令,手动启动server和broker。我们可以看一下readme:
这里可以按照readme所说,直接执行对应命令启动。执行完后,在终端中输入 jps -l 查看到进程即表示启动成功:
注意:这样虽然看着是启动成功了,但实际上,根据各种安装文档进行product/consumer测试时,
先启动consumer
export NAMESRV_ADDR=localhost:9876
sh /tools.sh org.apache.rocketmq.example.quickstart.Consumer再启动producer
export NAMESRV_ADDR=localhost:9876
sh tools.sh org.apache.rocketmq.example.quickstart.Producer
会出现如下报错:
org.apache.rocketmq.client.exception.MQClientException: No route info of this topic: TopicTest
这个地方的原因很重要!!!经过查阅资料可以知道,报这个错很大概率是因为:server和broker通信有问题!!!
为什么会有问题呢,原因就出在启动命令上:
a. 因为是docker内启动,server默认的ip就是127.0.0.1,但是broker启动时,不会追加server ip配置,需要手动填写(坑爹呢),因此,正确的启动broker的命令应该是:
nohup sh mqbroker -n localhost:9876 &
b. 当这样启动broker以后,执行测试是没有问题了,但是在代码远程使用,注册consumer的时候,你可能会收获这样的报错:
send message error dial tcp 172.17.0.4:10911: i/o timeout"
time="2023-02-26T01:23:32+08:00" level=error msg="get consumer list of group from broker error" broker="172.17.0.4:10911"
原因:我们在nas上装了docker服务,则docker里面的服务对外提供服务时,都是走的nas的端口映射,回到安装时的这张图:
可以看到,我们的rockermq的server对外的ip应该是:${nas_ip}:9876,因为broker要和server的ip对应,所以broker理论上ip也应该是${nas_ip}:10911才对,但是在报错信息上我们可以清晰的看到,broker的ip是${docker_ip},所以解决方案应该是配置一下broker的ip地址。
我们重新进入终端机,broker的配置位于./../conf目录下,绝对路径为
/home/rocketmq/rocketmq-4.9.4/conf
修改broker文件,追加如下两行:
namesrvAddr = 192.168.2.88:9876
brokerIP1 = 192.168.2.88
保存退出。回到bin目录下:cd ./../bin,kill掉旧的broker进程后,
执行如下命令:
nohup sh mqbroker -c /home/rocketmq/rocketmq-4.9.4/conf/broker.conf &
至此,群辉nas上docker安装的rocketmq,才能够真正的作为单机master服务进行使用。
查阅rocketmq的安装使用过程中,觉得命令行不方便,肯定是应该有可视化界面的项目,于是顺手搜了下,找到了这个:rocketmq-console-ng
实际体验下来感觉不错,这里也附一下docker的安装流程和配置。需要配置一下web端口映射和环境变量,如图:
端口映射:浏览器访问时,为${nas_ip}:本地端口
JAVA_OPTS一定要配置,需要和上面rmq安装的保持一致
namesrv.addr=${nas_ip}:9876
如果在代码运行过程中,发现有类似报错
the topic=xxx, it may not exist [recovered]
有如下解决方法:
方法1: 通过console创建这个topic:
方法2:broker配置时,允许自动创建topic:
autoCreateTopicEnable=ture
方法3:进shell用命令创建topic
sh mqadmin updateTopic -b ${nas_ip}:10911 -t ${topicName}
安装和研究各种报错花了一整天,整理这文章到深夜了,搜着搜着发现,rmq的可视化项目有个官方的:
https://github.com/apache/rocketmq-dashboard
然后docker也有对应的镜像,各位有时间倒可以研究研究。
生产者和消费者的golang代码如下:
import (
"github.com/apache/rocketmq-client-go/v2"
"github.com/apache/rocketmq-client-go/v2/primitive"
"github.com/apache/rocketmq-client-go/v2/producer"
"github.com/apache/rocketmq-client-go/v2/consumer"
)
var (
p rocketmq.Producer
co rocketmq.PushConsumer
)
var (
topic = "xxx"
group = "xxx"
)
// 初始化生产者
func InitProduct(c context.Context) {
p, _ = rocketmq.NewProducer(
producer.WithNameServer([]string{"${nas_ip}:9876"}), // 接入点地址
producer.WithRetry(2), // 重试次数
producer.WithGroupName(group), // 分组名称
)
err := p.Start()
if err != nil {
panic("")
}
}
// 初始化消费者
func InitConsumer(c context.Context) {
co, _ = rocketmq.NewPushConsumer(
consumer.WithNameServer([]string{"${nas_ip}:9876"}), // 接入点地址
consumer.WithConsumerModel(consumer.Clustering),
consumer.WithGroupName(group), // 分组名称
)
co.Subscribe(topic, consumer.MessageSelector{}, func(ctx context.Context, msg ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
for _, v := range msg {
fmt.Println(string(v.Body)) // v.Body : 消息主体
}
return consumer.ConsumeSuccess, nil
})
err := co.Start()
if err != nil {
panic(err)
}
}