RocketMQ容器化最佳实践

前言

在上一篇文章基于RocketMQ实现分布式事务我们完成基于消息队列实现分布式事务,为了方便后续的开发和环境统一,我们决定将RocketMQ容器化部署到服务器上。所以这篇文章就来演示一下笔者基于docker-compose完成RocketMQ容器化的过程。

本篇文章为了保证连贯性,所以在部署过程的介绍中不会涉及笔者遇到的问题和排查思路,所以当读者根据本文进行部署遇到问题的时候,可以直接到达问题清单一栏中查阅是否有相同情况,然后根据笔者思路进行排查修复。

容器化操作步骤

编写docker-compose

需要基于docker-compose开发就需要编写yml文件,查阅网上资料笔者找到了这样一份yml文件,内容比较长,笔者将配置参数含义都加以注释,读者可以根据需要进行修改,完成后将这份配置文件上传到服务器上即可。

# docker-compose 语法版本
version: '3'
services:
  # NameServer配置
  rocketmq-namesrv:
    # 镜像版本
    image: foxiswho/rocketmq:4.8.0
    # 容器名称
    container_name: rocketmq-namesrv
    # 重启
    restart: always
    # 端口映射
    ports:
    - 9876:9876
    volumes:
      # 日志文件、存储文件内外部容器卷映射
    - /app/cloud/rocketmq/namesrv/logs:/home/rocketmq/logs
    - /app/cloud/rocketmq/namesrv/store:/home/rocketmq/store
    environment:
      # jvm参数配置,调整rocket-mq空间
      JAVA_OPT_EXT: "-Duser.home=/home/rocketmq -Xms64M -Xmx64M -Xmn64m"
      # 启动命令
    command: ["sh","mqnamesrv"]
    # 网络连接配置
    networks:
      rocketmq_net:
        aliases:
        - rocketmq-namesrv

  # broker配置
  rocketmq-broker:
    image: foxiswho/rocketmq:4.8.0
    container_name: rocketmq-broker
    restart: always
    ports:
    - 10909:10909
    - 10911:10911
    volumes:
      # 日志、存储、broker配置文件宿主和容器文件映射
    - /app/cloud/rocketmq/broker/logs:/home/rocketmq/logs
    - /app/cloud/rocketmq/broker/store:/home/rocketmq/store
    - /app/cloud/rocketmq/broker/conf/broker.conf:/home/rocketmq/broker.conf
    environment:
      JAVA_OPT_EXT: "-Duser.home=/home/rocketmq -Xms64M -Xmx64M -Xmn64m"
      # 启动命令配置,指定broker配置地址,指定mq NameServer地址,设置topic自动创建为true
    command: ["sh","mqbroker","-c","/home/rocketmq/broker.conf","-n","rocketmq-namesrv:9876","autoCreateTopicEnable=true"]
    # 确保等NameServer启动后,在启动broker
    depends_on:
    - rocketmq-namesrv
    networks:
      rocketmq_net:
        aliases:
        - rocketmq-broker


  # mq控制台配置
  rocketmq-console:
    image: styletang/rocketmq-console-ng
    container_name: rocketmq-console
    restart: always
    ports:
    - 8180:8080
    environment:
      JAVA_OPTS: "-Drocketmq.namesrv.addr=rocketmq-namesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"
    depends_on:
    - rocketmq-namesrv
    networks:
      rocketmq_net:
        aliases:
        - rocketmq-console

# 自定义rocketmq容器网络配置为桥接模式确保当前容器和其他桥接容器、宿主机都是互通
networks:
  rocketmq_net:
    name: rocketmq_net
    driver: bridge

上文我们指定了broker.conf对应宿主机的位置为/app/cloud/rocketmq/broker/conf/broker.conf,所以我们就需要在宿主机上创建这个文件,并添加相应配置,内容如下,读者可以根据提示自行修改:

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
​
​
# 所属集群名字
brokerClusterName=DefaultCluster
​
# broker 名字,注意此处不同的配置文件填写的不一样,如果在 broker-a.properties 使用: broker-a,
# 在 broker-b.properties 使用: broker-b
brokerName=broker-a
​
# 0 表示 Master> 0 表示 Slave
brokerId=0
​
# nameServer地址,分号分割
# namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876
​
# 启动IP,如果 docker 报 com.alibaba.rocketmq.remoting.exception.RemotingConnectException: connect to <192.168.0.120:10909> failed
# 解决方式1 加上一句 producer.setVipChannelEnabled(false);,解决方式2 brokerIP1 设置宿主机IP,不要使用docker 内部IP
brokerIP1=服务器ip地址
​
# 在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
​
# 是否允许 Broker 自动创建 Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
​
# 是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
​
# Broker 对外服务的监听端口
listenPort=10911
​
# 删除文件时间点,默认凌晨4点
deleteWhen=04
​
# 文件保留时间,默认48小时
fileReservedTime=120
​
# commitLog 每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
​
# ConsumeQueue 每个文件默认存 30W 条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
​
# destroyMapedFileIntervalForcibly=120000
# redeleteHangedFileInterval=120000
# 检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
# 存储路径
# storePathRootDir=/home/ztztdata/rocketmq-all-4.1.0-incubating/store
# commitLog 存储路径
# storePathCommitLog=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/commitlog
# 消费队列存储
# storePathConsumeQueue=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/consumequeue
# 消息索引存储路径
# storePathIndex=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/index
# checkpoint 文件存储路径
# storeCheckpoint=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/checkpoint
# abort 文件存储路径
# abortFile=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/abort
# 限制的消息大小
maxMessageSize=65536
​
# flushCommitLogLeastPages=4
# flushConsumeQueueLeastPages=2
# flushCommitLogThoroughInterval=10000
# flushConsumeQueueThoroughInterval=60000
​
# Broker 的角色
# - ASYNC_MASTER 异步复制Master
# - SYNC_MASTER 同步双写Master
# - SLAVE
brokerRole=ASYNC_MASTER
​
# 刷盘方式
# - ASYNC_FLUSH 异步刷盘
# - SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
​
# 发消息线程池数量
# sendMessageThreadPoolNums=128
# 拉消息线程池数量
# pullMessageThreadPoolNums=128

笔者在安装过程中,遇到broker启动失败,错误码为253原因后文会详述,解决方式是修改我们宿主机关于RocketMQ的所属者和所属组

# 进入宿主机配置mq配置的文件夹,运行这条命令
chown -R 3000:3000 rocketmq/

前台启动观察日志

笔者将上文配置文件命名为mq.yml,到mq.yml文件所在位置,运行启动命令,注意由于本次部署为第一次部署,我们建议在前台运行方便观察日志确定服务运行情况。

docker-compose -f mq.yml up

当我们看到这段输出,就说明mqnameserver启动成功了。

在这里插入图片描述

按照启动顺序,我们再来看看broker,当我们在控制台看到boot success. serializeType=JSON and name server is rocketmq-namesrv:9876就说明broker也启动成功了。

在这里插入图片描述

mq-console则是一个控制台管理应用,看到spring boot项目启动成功的文本也就说明启动成功了。

在这里插入图片描述

此时我们可以查看docker进程就会发现这些项目端口映射是否和yml配置的一致。

[root@xxx ~]# docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS          PORTS                                                                                                               NAMES
e9851c9bdd48   foxiswho/rocketmq:4.8.0         "sh mqbroker -c /hom…"   48 minutes ago   Up 40 minutes   0.0.0.0:10909->10909/tcp, :::10909->10909/tcp, 9876/tcp, 10912/tcp, 0.0.0.0:10911->10911/tcp, :::10911->10911/tcp   rocketmq-broker
2120e73fafd1   styletang/rocketmq-console-ng   "sh -c 'java $JAVA_O…"   48 minutes ago   Up 40 minutes   0.0.0.0:8180->8080/tcp, :::8180->8080/tcp                                                                           rocketmq-console
6e8d0c48a533   foxiswho/rocketmq:4.8.0         "sh mqnamesrv"           48 minutes ago   Up 40 minutes   10909/tcp, 0.0.0.0:9876->9876/tcp, :::9876->9876/tcp, 10911-10912/tcp                                               rocketmq-namesrv

尝试打开RocketMQ控制台

确定完所有进程都正常启动,我们服务器必须先放行8180端口,然后就可以访问mq-console了,我们对着浏览器键入mq控制台的地址:

http://ip:8180/#/

这时我们就会看到控制台主界面,注意初次进入时界面为英文,读者可以右上角点击更换语言修改为中文,最终效果如下所示:

在这里插入图片描述

我们可以在集群一栏查看broker是否和broker.conf配置名字一致,同时也能监控查看近期消费情况,其余的主题、生产者、消费者等控制台信息笔者就不一一演示了,读者可以自行点击查看了解。

在这里插入图片描述

启动本地服务测试可用性

为了实现本地服务可以连接mq进行正常消费测试,我们的服务器必须放行10911109099876这几个端口,完成后修改各个spring boot应用关于mq的配置。

rocketmq:
  name-server: 服务器ip:9876
  producer:
    group: cloud-group

我们尝试将项目启动,并运行我们的测试代码,以笔者为例,运行的就是上一篇文章实现分布式事务的案例,完成后核服务控台、数据库数据是否正常修改。
确认上述步骤无误,我们再去观察mq控制台可以发现此时消费主题也多了一个我们自定义的消费主题:

在这里插入图片描述

我们配置的两个Java进程服务消费者也出现在控制台上,自此我们的应用消费mq控制台监控容器化部署配置就完成了

在这里插入图片描述

确保服务部署无误之后,将docker容器改为后台启动即可

docker-compose -f mq.yml up -d

问题清单

The compose file ‘./docker-compose.yaml‘ is invalid because:networks.rocketmq_net

在笔者启动docker-compose时,服务器输出了这样一段错误,查阅网上资料发现是docker-compose版本过低,导致无法识别这段语法,遇到这个问题我们升级docker-compose版本就好了,以笔者为例,参考StackOverflow的回答将其升级为1.28.5就解决了这个问题。

curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

broker文件不存在

在启动过程中笔者控制台输出了这样一段错误,原因是笔者第一版mqyml配置指定容器内部的broker文件在etc目录下,这个文件夹下并不存在这个文件,最后我们将broker.conf改到home目录下,配置内容为/app/cloud/rocketmq/broker/conf/broker.conf:/home/rocketmq/broker.conf问题得以解决。

rocketmq-broker     | java.io.FileNotFoundException: /etc/rocketmq/broker.conf (No such file or directory)
rocketmq-broker     |   at java.io.FileInputStream.open0(Native Method)
rocketmq-broker     |   at java.io.FileInputStream.open(FileInputStream.java:195)
rocketmq-broker     |   at java.io.FileInputStream.<init>(FileInputStream.java:138)
rocketmq-broker     |   at java.io.FileInputStream.<init>(FileInputStream.java:93)
rocketmq-broker     |   at org.apache.rocketmq.broker.BrokerStartup.createBrokerController(BrokerStartup.java:128)
rocketmq-broker     |   at org.apache.rocketmq.broker.BrokerStartup.main(BrokerStartup.java:58)

broker启动时输出exited with code 253

这个问题比较棘手,一开始笔者在控制台没有发现任何不正常的地方,排查半天网络问题都得不到解决,最终从网上得知是权限问题,最终在宿主机下所有关于mq的文件夹下修改所属者和所属组问题得以解决

chown -R 3000:3000 rocketmq/

本着求知的欲望笔者开始推断这个命令的作用,查阅宿主机下没有这个uid和gid为3000的用户,猜测有没有可能是在容器中存在一个需要操作宿主机权限的用户呢?对此笔者定位到mq容器id进入内部查看果然和猜测一致,在容器中确实存在一个名为rocketmquidgid都为3000的用户:

# 进入容器
[root@xxxx ~]# docker exec -it e9851c9bdd48 bash
# 查看容器中是否存在uid和gid为3000的用户
[rocketmq@e9851c9bdd48 bin]$ cat /etc/passwd |grep 3000
rocketmq:x:3000:3000::/home/rocketmq:/bin/bash

本地服务无法注册到mq上

这个问题较好定位,我们本机运行mq进行测试时没有问题,而部署到生产就连接不上,很大概率是网络连接不通,确定我们mq进程的所有端口号尝试按需放行即可。所以我们平时遇到这类问题优先和之前运行成功的样本进行比对猜测错误的原因加以调试。

小结

本次mq容器化部署整体过程相较之前遇到的问题会更多一些,从笔者的排查思路中看到,排查过程总是利用控制台输出关键字结合Google(这也是笔者部署之初采用前台启动的原因),注意是Google搜索引擎,该引擎定位问题速度相比百度和bing会更准确一些。
结合网上的种种方案推断解决思路加以调试,对于不懂的解决方式我们一定要吃透,就例如chown 这条命令,网上都没有解释问题的原因,对此笔者查阅了这条命令的作用查阅服务器关于用户信息反推到问题的源头,确保下次遇到类似问题解决速度会更快一些。

参考文献

docker-compose安装RocketMQ

关于 The compose file ‘./docker-compose.yaml‘ is invalid because:networks.fabric_network的解决方案

Deploy broker with docker-compose returns 253 error #17

Linux chown命令:修改文件和目录的所有者和所属组

Docker 搭建部署 RocketMQ 遇到broker 253问题

本地连接服务器上rocketmq 出现closeChannel: close the connection to remote address[] result: true

Docker 搭建部署 RocketMQ 遇到broker 253问题

docker run and get exited (253)

Unable to give network name in docker-compose

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/243908.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

移远通信5G智能模组SG520B系列正式上线,为智能终端轻松提供强大多媒体功能

12月13日&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;正式推出新一代 5G Sub-6GHz智能模组SG520B系列。 SG520B系列支持5G、Wi-Fi 6E和蓝牙等多种连接技术&#xff0c;且多媒体功能强大&#xff0c;推入市场后将可直接满足智能网关、智慧工业、智慧…

使用CFimagehost源码自建无需数据库支持的PHP图片托管服务

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

大数据笔记(待续)

mysql 缓存技术 数据库和缓存双写数据一致性问题常见的解决方案 常见方案通常情况下&#xff0c;我们使用缓存的主要目的是为了提升查询的性能。大多数情况下&#xff0c;我们是这样使用缓存的&#xff1a; 用户请求过来之后&#xff0c;先查缓存有没有数据&#xff0c;如果有…

做数据分析为何要学统计学(2)——如何估计总体概率分布

我们可以通过手头掌握的样本来估计总体的概率分布。这个过程由以下步骤组成。 第一步&#xff0c;我们采用Seaborn软件的histplot函数建立核密度图&#xff08;一种概率密度图&#xff09;。 import numpy as np #输入样本数据 xnp.array([2.12906357, 0.72736725, 1.0515282…

如何删除/替换3D模型的材质贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 在3D设计和动画领域&#xff0c;材质是呈现真实感和逼真效果的关键因…

电脑监控软件丨你能接受在电脑上安装吗

很多人说自己是不能接受老板在电脑上安装电脑监控软件的&#xff0c;怎么说呢&#xff0c;我自己本身是没有任何意见的。 我是可以接受的。 先来说说我的理由&#xff1a; 我是站在企业管理者的角度上&#xff0c;来思考这个问题的。老板花钱雇佣员工不是来公司来上网聊天打游…

【笔试强化】Day 1

文章目录 一、单选1.2.3.4.5.6. &#xff08;写错&#xff09;7. &#xff08;不会&#xff09;8. &#xff08;常错题&#xff09;9.10. &#xff08;写错&#xff09; 二、编程1. 组队竞赛题目&#xff1a;题解&#xff1a;代码&#xff1a; 2. 删除公共字符题目&#xff1a;…

自定义Axure元件库及原型图泳道图的绘制(详细不同类的案例)

目录 前言 一.自定义元件库 1.1 自定义元件库的作用 1.2 自定义元件的操作 二.流程图 2.1 流程图的作用 2.2 绘制流程图 2.3 简易流程图案例 三.泳道图 3.1 泳道图的作用 3.2 流程图和泳道图的区别 3.3 绘制泳道图 四.绘制前的准备 五.案例 4.1 门诊模块案例 4.2 …

mysql踩坑

关于安装 1报错&#xff1a;ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client具体代码如下&#xff1a; import mysql from "mysql"//连接数据库 const dbmysql.createPool({h…

前端体系:前端应用

目录 前端体系基础 html&#xff08;超文本标记语言&#xff09; css&#xff08;层叠样式单&#xff09; javascript&#xff08;&#xff09; 一、前端体系概述 二、前端框架 React Vue Angular 三、前端库和工具 lodash Redux Webpack 四、模块化和组件化 ES…

ZLMediaKit中的线程

EventLoop的线程模型 服务器通用的IO模型event-loop 非阻塞IO。线程模型可以是单线程&#xff0c;可以是多线程。对于已经普及了的多核环境&#xff0c;通常都是采用多线程。 通常一个线程中有一个EventLoop&#xff0c;比如accept是一个专门线程&#xff0c;accept后的fd分…

AJAX原理解析与案例实践,助你成为前端技术高手

大家有关于JavaScript知识点不知道可以去 &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 学习…

微信开发者工具安装教程

文章目录 下载安装包执行安装包 #微信开发者工具安装教程 下载安装包 官网网址 执行安装包 D:\Program Files (x86)\Tencent\微信web开发者工具\dll

D92-02-ASEMI快恢复二极管20A 200V

编辑&#xff1a;ll D92-02-ASEMI快恢复二极管20A 200V 型号&#xff1a;D92-02 品牌&#xff1a;ASEMI 封装&#xff1a;TO-247 特性&#xff1a;插件、快恢复二极管 最大平均正向电流&#xff1a;20A 最大重复峰值反向电压&#xff1a;200V 恢复时间&#xff1a;35ns…

nodejs使用express框架启动服务操作mysql数据库

描述: 首先在本地搭建mysql数据库,配置:host: ‘192.168.3.249’,user: ‘mkx’,password: ‘123456’,database: ‘gg’.测试连接正常.使用express写两个接口, 1.查询所有学生的接口,使用的get请求,无参数. 2.插入一条学生信息,使用post请求,body是一个json的学生信息{name:“…

计算机组成原理——存储器21-40

21、存储器存取周期是指&#xff08;C&#xff09; A、存储器的读出时间 B、存储器的写入时间 C、存储器进行连续读或写操作所允许的最短时间间隔 D、存储器进行一次读或写操作所需的平均时间 存取周期是存储器进行连续读或写操作所允许的最短时间间隔 存取时间是存储器进行一次…

【面试】数据库—优化—聚簇索引和非聚簇索引、回表查询

数据库—优化—聚簇索引和非聚簇索引、回表查询 1. 什么是聚簇索引什么是非聚簇索引 ? 聚集索引选取规则: 如果存在主键&#xff0c;主键索引就是聚集索引&#xff1b;如果不存在主键&#xff0c;将使用第一个唯一&#xff08;UNIQUE&#xff09;索引作为聚集索引&#xff1b…

Geek challenge 2023 EzHttp

打开链接需要使用post请求提交username和password 查看源码得到提示&#xff0c;爬虫想到robots协议 访问robots.txt 访问得到的路径&#xff1a;/o2takuXXs_username_and_password.txt 拿到用户名和密码&#xff1a; username:admin password:dm1N123456r00t# 进行post传参…

Windows 和 MacOS 上安装配置ADB(安卓调试桥)

一、Android 调试桥 (ADB) Android 调试桥&#xff08;ADB&#xff09; 是一款多功能命令行工具&#xff0c;它让你能够更便捷地访问和管理 Android 设备。使用 ADB 命令&#xff0c;你可以轻松执行以下操作 在设备上安装、复制和删除文件&#xff1b;安装应用程序&#xff1…

HTTP与HTTTPS的区别

目录 一、HTTP和HTTTPS的概念 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;&#xff1a; HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;&#xff1a; 二、HTTP 的 get 请求和 post 请求的区别&#xff1f; 三、HTTPS 的工作原理&#xff…