端口号描述

以配置的 ListenPort 为 10911 为例

端口号作用描述
9876nameserver 对外暴露的端口,允许消费者和生产者连接
10911ListenPort端口Broker 对外服务的监听端口
10909fastListen 端口在消费者或生产者中配置 isVipChannel 为 false 即可
10912HA 高可用端口,用于主从同步,为 Master 常见新的 socket 连接若没有开放,则无法连接到 Slave

1. 端口号计算

  • vip 通道端口为 ListenPort(10911-2) = 10909
  • HA 高可用端口为 ListenPort(10911+1) = 10912
  1. 端口号左右
  • vip 通道端口一般没什么作用
  • 而 HA 高可用端口用于主从集群时,创建 Master 和 Slave 之间的 socket 连接,故需要对外暴露
  1. 主从配置注意事项
  • clusterName和brokerName需要一致,才可以形成主备关系。
  • brokerId为0以及brokerRole为ASYNC_MASTER或者SYNC_MASTER代表为master
  • broker不为0以及brokerRole为SLAVE代表为slave

服务部署情况

共7个容器

  • 2个NameServer rocketmq镜像
  • 2 个master、 2个对应的slave rocketmq镜像
  • 1个管理控制台 rocketmq-console-ng镜像
服务名称IP地址监听端口号暴漏端口
nameserver-a172.18.0.398769876
nameserver-b172.18.0.498769877
broker-master-a172.18.0.51090910909,10910
broker-master-b172.18.0.61091910919,10920
broker-slave-a172.18.0.71091110911
broker-slave-b172.18.0.81092110921
console172.18.0.980808080

环境准备

虚拟机

vagrant 安装 centos7
指定ip: 192.168.10.200

创建RocketMq配置文件目录

创建集群需要的存储路径

mkdir -p  /tmp/data/rocketmq/nameserver-a/logs
mkdir -p  /tmp/data/rocketmq/nameserver-b/logs
mkdir -p  /tmp/data/rocketmq/nameserver-a/store
mkdir -p  /tmp/data/rocketmq/nameserver-b/store
mkdir -p  /tmp/data/rocketmq/broker-master-a/logs
mkdir -p  /tmp/data/rocketmq/broker-master-b/logs
mkdir -p  /tmp/data/rocketmq/broker-master-a/store
mkdir -p  /tmp/data/rocketmq/broker-master-b/store
mkdir -p  /tmp/data/rocketmq/broker-slave-a/logs
mkdir -p  /tmp/data/rocketmq/broker-slave-b/logs
mkdir -p  /tmp/data/rocketmq/broker-slave-a/store
mkdir -p  /tmp/data/rocketmq/broker-slave-b/store
mkdir -p  /tmp/etc/rocketmq/broker-master-a
mkdir -p  /tmp/etc/rocketmq/broker-master-b
mkdir -p  /tmp/etc/rocketmq/broker-slave-a
mkdir -p  /tmp/etc/rocketmq/broker-slave-b

创建broker配置文件

这里配置的主要信息有:

  1. 当前Broker对外暴露的端口号
  2. 注册到NameServer的地址,看到这里有两个地址,说明NameServer也是集群部署。
  3. 当前Broker的角色,是主还是从,这里表示是主。

broker-master-a

创建配置文件

vi /tmp/etc/rocketmq/broker-master-a/broker.conf

配置内容如下

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
#namesrvAddr 地址 填写docker内网地址即可
namesrvAddr=172.28.0.3:9876;172.28.0.4:9876
#启用自动创建主题
autoCreateTopicEnable=false
#这个很有讲究 如果是正式环境 这里一定要填写内网地址(安全)
#如果是用于测试或者本地这里建议要填外网地址,因为你的本地代码是无法连接到阿里云内网,只能连接外网。
#当前broker监听的IP
brokerIP1 = 192.168.10.200
#存在broker主从时,在broker主节点上配置了brokerIP2的话,broker从节点会连接主节点配置的brokerIP2来同步。
brokerIP2 = 192.168.10.200
#Broker 对外服务的监听端口
listenPort = 10909
#Broker角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=SYNC_MASTER
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH

broker-master-b

创建配置文件

vi /tmp/etc/rocketmq/broker-master-b/broker.conf

配置内容如下

brokerClusterName = DefaultCluster
brokerName = broker-b
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
#namesrvAddr 地址 填写docker内网地址即可
namesrvAddr=172.28.0.3:9876;172.28.0.4:9876
#启用自动创建主题
autoCreateTopicEnable=false
#这个很有讲究 如果是正式环境 这里一定要填写内网地址(安全)
#如果是用于测试或者本地这里建议要填外网地址,因为你的本地代码是无法连接到阿里云内网,只能连接外网。
#当前broker监听的IP
brokerIP1 = 192.168.10.200
#存在broker主从时,在broker主节点上配置了brokerIP2的话,broker从节点会连接主节点配置的brokerIP2来同步。
brokerIP2 = 192.168.10.200
#Broker 对外服务的监听端口
listenPort = 10919
#Broker角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=SYNC_MASTER
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH

broker-slave-a

创建配置文件

vi /tmp/etc/rocketmq/broker-slave-a/broker.conf

配置内容如下

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 1
deleteWhen = 04
fileReservedTime = 48
#namesrvAddr 地址 填写docker内网地址即可
namesrvAddr=172.28.0.3:9876;172.28.0.4:9876
#启用自动创建主题
autoCreateTopicEnable=false
#这个很有讲究 如果是正式环境 这里一定要填写内网地址(安全)
#如果是用于测试或者本地这里建议要填外网地址,因为你的本地代码是无法连接到阿里云内网,只能连接外网。
#当前broker监听的IP
brokerIP1 = 192.168.10.200
#存在broker主从时,在broker主节点上配置了brokerIP2的话,broker从节点会连接主节点配置的brokerIP2来同步。
brokerIP2 = 192.168.10.200
#Broker 对外服务的监听端口
listenPort = 10911
#Broker角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=SLAVE
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH

broker-slave-b

创建配置文件

vi /tmp/etc/rocketmq/broker-slave-b/broker.conf

配置内容如下

brokerClusterName = DefaultCluster
brokerName = broker-b
brokerId = 1
deleteWhen = 04
fileReservedTime = 48
#namesrvAddr 地址 填写docker内网地址即可
namesrvAddr=172.28.0.3:9876;172.28.0.4:9876
#启用自动创建主题
autoCreateTopicEnable=false
#这个很有讲究 如果是正式环境 这里一定要填写内网地址(安全)
#如果是用于测试或者本地这里建议要填外网地址,因为你的本地代码是无法连接到阿里云内网,只能连接外网。
#当前broker监听的IP
brokerIP1 = 192.168.10.200
#存在broker主从时,在broker主节点上配置了brokerIP2的话,broker从节点会连接主节点配置的brokerIP2来同步。
brokerIP2 = 192.168.10.200
#Broker 对外服务的监听端口
listenPort = 10921
#Broker角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=SLAVE
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH

Docker-compose文件

共7个容器

  • 2个NameServer rocketmq镜像
  • 2 个master、 2个对应的slave rocketmq镜像
  • 1个管理控制台 rocketmq-console-ng镜像
version: '2.1'
services:
  nameserver-a:
    image: rocketmqinc/rocketmq
    container_name: nameserver-a
    networks:
      rocketmq_net:
        ipv4_address: 172.28.0.3
    environment:
      MAX_POSSIBLE_HEAP: 100000000
    ports:
      - 9876:9876
    volumes:
      - /tmp/data/rocketmq/nameserver-a/logs:/root/logs
      - /tmp/data/rocketmq/nameserver-a/store:/root/store
    command: sh mqnamesrv
  nameserver-b:
    image: rocketmqinc/rocketmq
    container_name: nameserver-b
    networks:
      rocketmq_net:
        ipv4_address: 172.28.0.4
    environment:
      MAX_POSSIBLE_HEAP: 100000000
    ports:
      - 9877:9876
    volumes:
      - /tmp/data/rocketmq/nameserver-b/logs:/root/logs
      - /tmp/data/rocketmq/nameserver-b/store:/root/store
    command: sh mqnamesrv
  broker-master-a:
    image: rocketmqinc/rocketmq
    container_name: rmqbroker-master-a
    networks:
      rocketmq_net:
        ipv4_address: 172.28.0.5
    environment:
      MAX_POSSIBLE_HEAP: 200000000
    ports:
      - 10909:10909
      - 10910:10910
    volumes:
      - /tmp/data/rocketmq/broker-master-a/logs:/root/logs
      - /tmp/data/rocketmq/broker-master-a/store:/root/store
      - /tmp/etc/rocketmq/broker-master-a/broker.conf:/opt/rocketmq/conf/broker.conf
    command: sh mqbroker -c /opt/rocketmq/conf/broker.conf
    depends_on:
      - nameserver-a
      - nameserver-b
  broker-master-b:
    image: rocketmqinc/rocketmq
    container_name: rmqbroker-master-b
    networks:
      rocketmq_net:
        ipv4_address: 172.28.0.6
    environment:
      MAX_POSSIBLE_HEAP: 200000000
    ports:
      - 10919:10919
      - 10920:10920
    volumes:
      - /tmp/data/rocketmq/broker-master-b/logs:/root/logs
      - /tmp/data/rocketmq/broker-master-b/store:/root/store
      - /tmp/etc/rocketmq/broker-master-b/broker.conf:/opt/rocketmq/conf/broker.conf
    command: sh mqbroker -c /opt/rocketmq/conf/broker.conf
    depends_on:
      - nameserver-a
      - nameserver-b
  broker-slave-a:
    image: rocketmqinc/rocketmq
    container_name: rmqbroker-slave-a
    networks:
      rocketmq_net:
        ipv4_address: 172.28.0.7
    environment:
      MAX_POSSIBLE_HEAP: 200000000
    ports:
      - 10911:10911
    volumes:
      - /tmp/data/rocketmq/broker-slave-a/logs:/root/logs
      - /tmp/data/rocketmq/broker-slave-a/store:/root/store
      - /tmp/etc/rocketmq/broker-slave-a/broker.conf:/opt/rocketmq/conf/broker.conf
    command: sh mqbroker -c /opt/rocketmq/conf/broker.conf
    depends_on:
      - nameserver-a
      - nameserver-b
      - broker-master-a
      - broker-master-b
  broker-slave-b:
    image: rocketmqinc/rocketmq
    container_name: rmqbroker-slave-b
    networks:
      rocketmq_net:
        ipv4_address: 172.28.0.8
    environment:
      MAX_POSSIBLE_HEAP: 200000000
    ports:
      - 10921:10921
    volumes:
      - /tmp/data/rocketmq/broker-slave-b/logs:/root/logs
      - /tmp/data/rocketmq/broker-slave-b/store:/root/store
      - /tmp/etc/rocketmq/broker-slave-b/broker.conf:/opt/rocketmq/conf/broker.conf
    command: sh mqbroker -c /opt/rocketmq/conf/broker.conf
    depends_on:
      - nameserver-a
      - nameserver-b
      - broker-master-a
      - broker-master-b
  console:
    image: styletang/rocketmq-console-ng
    container_name: rocketmq-console-ng
    networks:
      rocketmq_net:
        ipv4_address: 172.28.0.9
    ports:
      - 8080:8080
    depends_on:
      - nameserver-a
      - nameserver-b
    environment:
      - JAVA_OPTS= -Dlogging.level.root=info -Drocketmq.namesrv.addr=172.28.0.3:9876;172.28.0.4:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false
networks:
  rocketmq_net:
    ipam:
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1

启动容器

启动

docker-compose -f docker-compose-rocketmq-cluster.yml up -d
在这里插入图片描述

检查启动状态

docker-compose -f docker-compose-rocketmq-cluster.yml ps

在这里插入图片描述

访问控制台

在浏览器中输入:http://{docker宿主机ip}:8080/ 看到如下界面,表示安装成功

8080是 rocketmq-console-ng 容器的访问端口

查看集群情况

在这里插入图片描述

手动创建主题

因为创建双主双从,并且关闭了自动主题创建,需要手动创建主题
在这里插入图片描述

代码发送测试

示例代码

  1. 生产者配置文件
rocketmq.name-server=192.168.10.200:9877
rocketmq.producer.group=my-group1
rocketmq.producer.sendMessageTimeout=300000

# properties used in the application
demo.rocketmq.topic=string-topic
demo.rocketmq.orderTopic=order-paid-topic
demo.rocketmq.msgExtTopic=message-ext-topic
demo.rocketmq.transTopic=spring-transaction-topic
demo.rocketmq.topic.user=user-topic

demo.rocketmq.bytesRequestTopic=bytesRequestTopic:tagA
demo.rocketmq.stringRequestTopic=stringRequestTopic:tagA
demo.rocketmq.objectRequestTopic=objectRequestTopic:tagA
demo.rocketmq.genericRequestTopic=genericRequestTopic:tagA

demo.rocketmq.extNameServer=192.168.10.200:9877
# default producer tls config
rocketmq.producer.tls-enable=false
# self ext producer tls config
demo.rocketmq.ext.useTLS=false
  1. 消费者配置文件
spring.application.name=rocketmq-consume-demo

rocketmq.name-server=192.168.10.200:9877
rocketmq.consumer.group=my-group1
rocketmq.consumer.topic=test
# properties used in application code
demo.rocketmq.topic=string-topic
demo.rocketmq.bytesRequestTopic=bytesRequestTopic
demo.rocketmq.stringRequestTopic=stringRequestTopic
demo.rocketmq.objectRequestTopic=objectRequestTopic
demo.rocketmq.genericRequestTopic=genericRequestTopic
demo.rocketmq.bytesRequestConsumer=bytesRequestConsumer
demo.rocketmq.stringRequestConsumer=stringRequestConsumer
demo.rocketmq.objectRequestConsumer=objectRequestConsumer
demo.rocketmq.genericRequestConsumer=genericRequestConsumer
demo.rocketmq.orderTopic=order-paid-topic
demo.rocketmq.msgExtTopic=message-ext-topic
demo.rocketmq.transTopic=spring-transaction-topic
demo.rocketmq.topic.user=user-topic
demo.rocketmq.tag=tagA
# another nameserver different global
demo.rocketmq.myNameServer=192.168.10.200:9877
# my Consumer TLS Listener
demo.rocketmq.tlsEnable=false
# default LitePullConsumer TLS
rocketmq.consumer.tlsEnable=false
# ext rocketmq consumer template TLS
demo.ext.consumer.tlsEnable=false

发送消息

请查看 《4 常见使用案例》 文档

SLAVE_NOT_AVAILABLE问题

搭建了 rocketmq 的双主双从集群,在使用同步模式下,在向 master 发送消息时,返回的消息状态码为 SLAVE_NOT_AVAILABLE

解决方式
这个问题是由于没有开放对应端口,在配置文件中找到自己设置的 Master 开放端口:

复制

#Broker 对外服务的监听端口
listenPort = 10909

  • rocketmq 默认端口:9876
  • 配置的 ListenPort 端口:10909
  • vip 通道端口为:ListenPort - 2 = 10907
  • HA 通道端口为: ListenPort + 1 = 10910

vip 通道端口一般没什么作用,而 HA 高可用端口用于主从集群时,创建 Master 和 Slave 之间的 socket 连接,故需要对外暴露。

参考链接

安装docker 双主双从集群

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐