目录

rocketmq集群搭建

集群搭建方式

集群特点

  • NameServer是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
  • Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与NameServer集群中的所有节点建立长连接,定时注册Topic信息到所有NameServer。
  • Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。
  • Consumer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则可以在broker内部配置。

NameServer的无状态

NameServer是无状态的,在broker启动的时候会向NameServer集群中的每个节点上报自己的信息,NameServer集群中的每个节点都是无差异的,不需要做数据同步,所以是无状态的。

Broker主从

  • Borker(Master)面向producer的写
  • Borker(Slave)面向consumer的读

如何知道broker的主从关系,NameServer通过BrokerName是否相同区分是否是同一组,在同一组内是通过brokerid来区分主从,0代表主,非0代表从。

架构模式

单Master模式

这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用于本地测试。

多Master模式

一个集群无Slave,全是Master,例如2个Master或者3个Master,这种模式的优缺点如下:

  • 优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高;
  • 缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。

多Master多Slave模式(异步)

每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级),这种模式的优缺点如下:

  • 优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费(主节点不再写入),而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样;
  • 缺点:Master宕机,磁盘损坏情况下会丢失少量消息。

多Master多Slave模式(同步)

每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:

  • 优点:数据与服务都无单点故障,Master宕机情况下,消息不会丢失,服务可用性与数据可用性都非常高;
  • 缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。

DLedger集群

上面讲的两个多master多slave都是主从同步方式,主节点挂了就停止写入消息只会让消费者进行读取。DLedger集群是基于基于 raft 协议的多副本日志复制设计原理,在主节点挂掉后可以重新选主。可以将简单地将上面两种模式归类为主从同步模式,DLedger集群为主从切换模式。

双主双从同步架构搭建

总体架构

消息高可用采用2m-2s(同步双写)方式

http://img.cana.space/picStore/20201126223148.png

集群工作流程

  1. 启动NameServer,NameServer起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。
  2. Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。
  3. 收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。
  4. Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。
  5. Consumer跟Producer类似,跟其中一台NameServer建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,开始消费消息。

说明

使用dockfile构建镜像,上传到阿里hub;使用docker-compose搭建集群(namesrv2个,broker2主2从);修改4个broker的配置文件,配置成主从环境。

  • rocketmq版本:4.4.0
  • jre:8

步骤

  1. 准备软件包,由于namesrv和broker默认启动内存设置过大,需要修改默认内存,unzip软件包,修改启动脚本为可配置方式后重新zip

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    # 1.docker镜像工作目录,软件包,jre是由于rocketmq需要jre环境
    # david @ Davids-Macbook-Pro in ~/docker/docker-config/rocketmqbase [13:46:15]
    $ ll
    total 132640
    -rw-r--r--  1 david  staff    12M  6  1  2019 rocketmq-all-4.4.0-bin-release.zip
    -rw-r--r--@ 1 david  staff    53M 11 20 22:45 server-jre-8u271-linux-x64.tar.gz
    # 2.修改 runbroker.sh 和 runserver.sh为可配置方式
    # 参考:https://hub.docker.com/r/foxiswho/rocketmq
    # 2.1 解压缩rocketmq-all-4.4.0-bin-release.zip
    $ unzip rocketmq-all-4.4.0-bin-release.zip
    # 2.2 修改runbroker.sh 和 runserver.sh
    $ cd rocketmq-all-4.4.0-bin-release/bin
    # 将 runbroker.sh 和 runserver.sh 中的 -server -Xms4g -Xmx4g -Xmn2g 替换成${JAVA_OPT_EXT}
    # 2.3 重新压缩
    $ rm rocketmq-all-4.4.0-bin-release.zip
    # -r 表示子目录子文件全部压缩为zip;这部分比较重要,不然的话只有something这个文件夹被压缩,里面的没有被压缩进去
    # -o 表示设置所有被压缩文件的最后修改时间为当前压缩时间
    $ zip -r -o rocketmq-all-4.4.0-bin-release.zip rocketmq-all-4.4.0-bin-release
    $ rm -rf rocketmq-all-4.4.0-bin-release
    

    这样编写dockerfile的时候设置环境变量JAVA_OPT_EXT就可以将变量值传入到启动参数位置了。


    更新,增加了远程调试口子

    runbroker.sh和runserver.sh一样远程调试部分一样。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    #===========================================================================================
    # JVM Configuration
    #===========================================================================================
    JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT} -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
    ...
       
    # 开远程调试口子
    if [[ ${DEBUG} ]];then
        [ ${DEBUG} = Y ] && JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
        echo $JAVA_OPT
    fi
    

    更新!!! -_-||, 上面两个配置不用这么麻烦,仔细看了下配置,两个启动文件里已经考虑到启动参数配置和远程调试了

    1. JAVA_OPT_EXT 已经给配置好了,不用自己再额外配置到文件里面
    2. 远程调试将JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"这一行注释打开就行,当然也可以像我上面这样弄成可配置的
  2. 编写Dockerfile

    参考:foxiswho/rocketmq:server-4.7.0

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    FROM registry.cn-hangzhou.aliyuncs.com/lienhui68/centos:8
    MAINTAINER lienhui68<lienhui1992@gmail.com>
       
    LABEL name="lienhui68 rocketmqbase image" \
    build-date="20201125"
       
    ADD server-jre-8u271-linux-x64.tar.gz /home/
    # dockerfile ADD不支持zip
    # https://github.com/moby/moby/issues/15036
    # 曲径救国
    COPY rocketmq-all-4.4.0-bin-release.zip /home/
       
    # 安装unzip
    RUN yum -y install unzip
    # 手动解压
    WORKDIR /home/
    RUN unzip /home/rocketmq-all-4.4.0-bin-release.zip
    # 手动删除
    RUN rm /home/rocketmq-all-4.4.0-bin-release.zip
       
    ENV WORKPATH /home/rocketmq-all-4.4.0-bin-release/
    WORKDIR $WORKPATH
       
    # 设置JAVA_HOME,可以现在本地解压看得到的是什么目录
    ENV JAVA_HOME /home/jdk1.8.0_271
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV PATH $JAVA_HOME/bin:$PATH
       
    # namesrv监听端口
    EXPOSE 9876
    # Broker启动时,实际上会监听3个端口:10909、10911、10912,这三个端口由Broker内部不同的组件使用,作用分别如下
    # remotingServer:监听listenPort配置项指定的监听端口,默认10911 
    # fastRemotingServer:监听端口值listenPort-2,即默认为10909
    # HAService:监听端口为值为listenPort+1,即10912,该端口用于Broker的主从同步
    EXPOSE 10909 10911 10912
    # 远程调试端口
    EXPOSE 9555
    # 使镜像根据用户变量设置,既可以支持启动namesrv也可以启动broker
    # 注意使用重定向,否则启动服务后会阻塞
    # [ $RUNWHAT = NAMESRV ] && $(nohup sh bin/mqnamesrv > /dev/null 2 >&1 &) || $(nohup sh bin/mqbroker > /dev/null 2 >&1 &)
    # 上面这样写就没有前台进程了,导致容器一启动就退出,这个是 docker 的机制问题,后台启动后,会立即自杀,因为他觉得他没事可做了.
    # autoCreateTopicEnable=true 自动创建topic,用于开发环境
    CMD [ $RUNWHAT = NAMESRV ] && $(sh bin/mqnamesrv) || $(sh bin/mqbroker -c conf/mqbroker.properties autoCreateTopicEnable=false)
    

    此处巨坑,原先没有配置-c conf/mqbroker.properties,在默认的配置文件broker.conf下做集群配置结果怎么都不生效,网上查了一下说是必须要用properties文件才可以。。。

  3. 构建镜像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    $ ll
    total 132656
    -rw-r--r--@ 1 david  staff   1.5K 11 25 15:34 Dockerfile
    -rw-r--r--  1 david  staff    12M  6  1  2019 rocketmq-all-4.4.0-bin-release.zip
    -rw-r--r--@ 1 david  staff    53M 11 20 22:45 server-jre-8u271-linux-x64.tar.gz
       
    $ docker build -t lienhui68/rocketmqbase:4.4.0 .
    Successfully built d9260895471a
    Successfully tagged lienhui68/rocketmqbase:4.4.0
    
  4. check镜像能否正常使用

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    # 如果容器有问题启动不了,可以run进入容器查看
    $ docker run -p 9876:9876 \
    -e RUNWHAT=NAMESRV \
    -e "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m" \
    -it \
    --name rocketmq-namesrv \
    lienhui68/rocketmqbase:4.4.0 \
    /bin/bash
       
    # 1.测试namesrv
    $ docker run -p 9876:9876 \
    -e RUNWHAT=NAMESRV \
    -e "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m" \
    -d --name rocketmq-namesrv \
    lienhui68/rocketmqbase:4.4.0
    a2
    # 进入容器查看启动日志
    $ de a2 bash
    [root@a21c145084e1 rocketmq-all-4.4.0-bin-release]# tail -20f ~/logs/rocketmqlogs/namesrv.log
    ...
    2020-11-25 17:58:50 INFO NettyEventExecutor - NettyEventExecutor service started
    2020-11-25 17:58:50 INFO main - The Name Server boot success. serializeType=JSON
    ...
    # 2.再测试broker
    $ docker run -p 10909:10909 -p 10911:10911 -p 10912:10912 \
    -e RUNWHAT=BROKER \
    -e "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m" \
    -d --name rocketmq-broker \
    lienhui68/rocketmqbase:4.4.0
    0cdec69a27a12fb66a08e7e0715eea591fe3124fec640ba724a31460529c67eb
    # 进入容器查看启动日志
    $ de 0c bash
    [root@0cdec69a27a1 rocketmq-all-4.4.0-bin-release]# tail -20f ~/logs/rocketmqlogs/
    ...
    2020-11-25 18:08:26 INFO main - Start transaction service!
    2020-11-25 18:08:26 INFO main - The broker[0cdec69a27a1, 172.17.0.4:10911] boot success. serializeType=JSON
    
  5. 上传镜像到阿里仓库

    1
    2
    3
    4
    5
    6
    7
    
    # 阿里云docker镜像仓库地址:https://cr.console.aliyun.com/cn-hangzhou/instances/repositories
    # 先在远程创建镜像残酷 rocketmqbase
    # 本地镜像打tag
    $ docker tag d9  registry.cn-hangzhou.aliyuncs.com/lienhui68/rocketmqbase:4.4.0
    # 推送到远程
    $ docker push registry.cn-hangzhou.aliyuncs.com/lienhui68/rocketmqbase:4.4.0
    # 在阿里云镜像仓库中可以看到已经上传上来了
    
  6. docker-compose编排集群(namesrv2个,broker2主2从)

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    
    version: '2'
    services: 
        namesrv_1: 
            image: lienhui68/rocketmqbase:4.4.0
            container_name: namesrv_1
            volumes: 
                - ./namesrv_1/log:/root/logs/rocketmqlogs
            restart: always
            environment:
                - "TZ=Asia/Shanghai"
                - "RUNWHAT=NAMESRV"
                - "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m"
                - "DEBUG=Y"
            ports: 
                - 9876:9876
                - 9555:9555
            networks: 
                rocketmq: 
                    ipv4_address: 183.40.0.2 # 设置静态ipv4地址
        namesrv_2: 
            image: lienhui68/rocketmqbase:4.4.0
            container_name: namesrv_2
            volumes: 
                - ./namesrv_2/log:/root/logs/rocketmqlogs
            restart: always
            environment:
                - "TZ=Asia/Shanghai"
                - "RUNWHAT=NAMESRV"
                - "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m"
                - "DEBUG=Y"
            ports: 
                - 9877:9876
                - 9556:9555
            networks: 
                rocketmq: 
                    ipv4_address: 183.40.0.3 # 设置静态ipv4地址
        broker_m_1: 
            image: lienhui68/rocketmqbase:4.4.0
            container_name: broker_m_1
            volumes: 
                - ./broker_m_1/log:/root/logs/rocketmqlogs
                - ./broker_m_1/store:/home/rocketmq-all-4.4.0-bin-release/store
                - ./conf/broker_m_1.properties:/home/rocketmq-all-4.4.0-bin-release/conf/mqbroker.properties
            restart: always
            environment:
                - "TZ=Asia/Shanghai"
                - "RUNWHAT=BROKER"
                - "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m"
                - "DEBUG=Y"
            ports: 
                - 10909:10909 # fastRemotingServer:监听端口值listenPort-2
                - 10911:10911 # broekr服务端监听端口
                - 10912:10912 # Master监听端口,从服务器连接该端口,监听端口值listenPort+1
                - 9557:9555
            networks: 
                rocketmq: 
                    ipv4_address: 183.40.0.4 # 设置静态ipv4地址
            depends_on:
                - namesrv_1
                - namesrv_2
        broker_m_2: 
            image: lienhui68/rocketmqbase:4.4.0
            container_name: broker_m_2
            volumes: 
                - ./broker_m_2/log:/root/logs/rocketmqlogs
                - ./broker_m_2/store:/home/rocketmq-all-4.4.0-bin-release/store
                - ./conf/broker_m_2.properties:/home/rocketmq-all-4.4.0-bin-release/conf/mqbroker.properties
            restart: always
            environment:
                - "TZ=Asia/Shanghai"
                - "RUNWHAT=BROKER"
                - "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m"
                - "DEBUG=Y"
            ports: 
                - 11909:11909 # fastRemotingServer:监听端口值listenPort-2
                - 11911:11911 # broekr服务端监听端口
                - 11912:11912 # Master监听端口,从服务器连接该端口,监听端口值listenPort+1
                - 9558:9555
            networks: 
                rocketmq: 
                    ipv4_address: 183.40.0.5 # 设置静态ipv4地址
            depends_on:
                - namesrv_1
                - namesrv_2
        broker_s_1: 
            image: lienhui68/rocketmqbase:4.4.0
            container_name: broker_s_1
            volumes: 
                - ./broker_s_1/log:/root/logs/rocketmqlogs
                - ./broker_s_1/store:/home/rocketmq-all-4.4.0-bin-release/store
                - ./conf/broker_s_1.properties:/home/rocketmq-all-4.4.0-bin-release/conf/mqbroker.properties
            restart: always
            environment:
                - "TZ=Asia/Shanghai"
                - "RUNWHAT=BROKER"
                - "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m"
                - "DEBUG=Y"
            ports: 
                - 12909:12909 # fastRemotingServer:监听端口值listenPort-2
                - 12911:12911 # broekr服务端监听端口
                - 9559:9555
            networks: 
                rocketmq: 
                    ipv4_address: 183.40.0.6 # 设置静态ipv4地址
            depends_on:
                - namesrv_1
                - namesrv_2
                - broker_m_1
        broker_s_2: 
            image: lienhui68/rocketmqbase:4.4.0
            container_name: broker_s_2
            volumes: 
                - ./broker_s_2/log:/root/logs/rocketmqlogs
                - ./broker_s_2/store:/home/rocketmq-all-4.4.0-bin-release/store
                - ./conf/broker_s_2.properties:/home/rocketmq-all-4.4.0-bin-release/conf/mqbroker.properties
            restart: always
            environment:
                - "TZ=Asia/Shanghai"
                - "RUNWHAT=BROKER"
                - "JAVA_OPT_EXT=-Xms256M -Xmx256M -Xmn128m"
                - "DEBUG=Y"
            ports: 
                - 13909:13909 # fastRemotingServer:监听端口值listenPort-2
                - 13911:13911 # broekr服务端监听端口
                - 9560:9555
            networks: 
                rocketmq: 
                    ipv4_address: 183.40.0.7 # 设置静态ipv4地址
            depends_on:
                - namesrv_1
                - namesrv_2
                - broker_m_2
        rmqconsole:
            image: styletang/rocketmq-console-ng
            container_name: rmqconsole
            ports: 
                - 8090:8080
            networks: 
                rocketmq: 
                    ipv4_address: 183.40.0.8 # 设置静态ipv4地址
            depends_on:
                - namesrv_1
                - namesrv_2
    networks: # 使用自定义网络
        rocketmq:
            # ipam插件只在compose version 2中好使,
            # issue:https://github.com/docker/docker.github.io/pull/1636
            ipam: # 要使用静态ip必须使用ipam插件
                config:
                - subnet: 183.40.0.0/16 # 网段/16位掩码
                  gateway: 183.40.0.1 # 网关地址
    

    更新:增加rmqconsole

    为了正常启动先拷贝broker.conf到conf目录下,共4份文件

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    
    # 配置文件
    $ cp ~/soft/rocketmq-all-4.4.0-bin-release/conf/broker.conf ./broker_m_1.conf
    $ cp broker_m_1.conf broker_m_2.conf
    $ cp broker_m_1.conf broker_s_1.conf
    $ cp broker_m_1.conf broker_s_2.conf
    # 启动
    # david @ Davids-Macbook-Pro in ~/docker/compose-config/rocketmq [19:17:31]
    $ dcp -f 2n_2m_2s.yaml up -d
    Creating network "rocketmq_rocketmq" with the default driver
    Creating namesrv_1 ... done
    Creating namesrv_2 ... done
    Creating broker_m_2 ... done
    Creating broker_m_1 ... done
    Creating broker_s_1 ... done
    Creating broker_s_2 ... done
    # 查看ip
    # david @ Davids-Macbook-Pro in ~/docker/compose-config/rocketmq [19:17:45]
    $ docker_ip
    /broker_s_2 - 183.40.0.7
    /broker_s_1 - 183.40.0.6
    /broker_m_2 - 183.40.0.5
    /broker_m_1 - 183.40.0.4
    /namesrv_2 - 183.40.0.3
    /namesrv_1 - 183.40.0.2
    # 查看启动日志
    # namesrv_1
    $ tail -20f namesrv_1/log/namesrv.log
    2020-11-25 19:17:58 INFO NettyEventExecutor - NettyEventExecutor service started
    # broker_m_1
    $ tail -20f broker_m_1/log/broker.log
    2020-11-25 19:18:01 INFO PullRequestHoldService - PullRequestHoldService service started
    # broker_s_2
    $ tail -20f broker_s_2/log/broker.log
    2020-11-25 19:18:03 INFO PullRequestHoldService - PullRequestHoldService service started
    

    ok,所有容器启动正常,接下来就是主从同步配置了

  7. 修改broker配置文件(broker.conf)

    1. broker_m_1

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      
      #所属集群名字
      brokerClusterName=rocketmq-cluster
      #broker名字,注意此处不同的配置文件填写的不一样
      brokerName=broker-1
      #0 表示 Master,>0 表示 Slave
      brokerId=0
      #nameServer地址,分号分割
      namesrvAddr=183.40.0.2:9876;183.40.0.3:9876
      #在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
      defaultTopicQueueNums=4
      #是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
      autoCreateTopicEnable=true
      #是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
      autoCreateSubscriptionGroup=true
      #Broker 对外服务的监听端口,4个不能一样,因为配置了对外暴露brokerIP1,外面使用默认都是用的宿主机ip:listenPort
      listenPort=10911
      #删除文件时间点,默认凌晨 4点
      deleteWhen=04
      #文件保留时间,默认 48 小时
      fileReservedTime=120
      #commitLog每个文件的大小默认1G,单位byte,1073741824刚好1g
      mapedFileSizeCommitLog=1073741824
      #ConsumeQueue每个文件默认存30W条,根据业务情况调整
      mapedFileSizeConsumeQueue=300000
      #destroyMapedFileIntervalForcibly=120000
      #redeleteHangedFileInterval=120000
      #检测物理文件磁盘空间达到比例
      diskMaxUsedSpaceRatio=88
      #存储路径
      storePathRootDir=/home/rocketmq-all-4.4.0-bin-release/store
      #commitLog 存储路径
      storePathCommitLog=/home/rocketmq-all-4.4.0-bin-release/store/commitlog
      #消费队列存储路径存储路径
      storePathConsumeQueue=/home/rocketmq-all-4.4.0-bin-release/store/consumequeue
      #消息索引存储路径
      storePathIndex=/home/rocketmq-all-4.4.0-bin-release/store/index
      #checkpoint 文件存储路径
      storeCheckpoint=/home/rocketmq-all-4.4.0-bin-release/store/checkpoint
      #abort 文件存储路径
      abortFile=/home/rocketmq-all-4.4.0-bin-release/store/abort
      #限制的消息大小,64KB
      maxMessageSize=65536
      #flushCommitLogLeastPages=4
      #flushConsumeQueueLeastPages=2
      #flushCommitLogThoroughInterval=10000
      #flushConsumeQueueThoroughInterval=60000
      #Broker 的角色
      #- ASYNC_MASTER 异步复制Master
      #- SYNC_MASTER 同步双写Master
      #- SLAVE
      brokerRole=SYNC_MASTER
      #刷盘方式
      #- ASYNC_FLUSH 异步刷盘
      #- SYNC_FLUSH 同步刷盘
      flushDiskType=SYNC_FLUSH
      #checkTransactionMessageEnable=false
      #发消息线程池数量
      #sendMessageThreadPoolNums=128
      #拉消息线程池数量
      #pullMessageThreadPoolNums=128
      # 宿主机IP
      brokerIP1=192.168.1.4
      #允许从服务器落户的最大偏移字节数,默认为256M。超过该值则表示该Slave不可用
      haSlaveFallbehindMax=268435456
      
    2. broker_m_2

      其他同broker_m_1

      1
      2
      3
      
      brokerName=broker-2
      #Broker 对外服务的监听端口
      listenPort=11911
      
    3. broker_s_1

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      
      #所属集群名字
      brokerClusterName=rocketmq-cluster
      #broker名字,要和主节点一致
      brokerName=broker-1
      #0 表示 Master,>0 表示 Slave
      brokerId=1
      #nameServer地址,分号分割
      namesrvAddr=183.40.0.2:9876;183.40.0.3:9876
      #在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
      defaultTopicQueueNums=4
      #是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
      autoCreateTopicEnable=true
      #是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
      autoCreateSubscriptionGroup=true
      #Broker 对外服务的监听端口
      listenPort=12911
      #删除文件时间点,默认凌晨 4点
      deleteWhen=04
      #文件保留时间,默认 48 小时
      fileReservedTime=120
      #commitLog每个文件的大小默认1G,单位byte,1073741824刚好1g
      mapedFileSizeCommitLog=1073741824
      #ConsumeQueue每个文件默认存30W条,根据业务情况调整
      mapedFileSizeConsumeQueue=300000
      #destroyMapedFileIntervalForcibly=120000
      #redeleteHangedFileInterval=120000
      #检测物理文件磁盘空间达到比例
      diskMaxUsedSpaceRatio=88
      #存储路径
      storePathRootDir=/home/rocketmq-all-4.4.0-bin-release/store
      #commitLog 存储路径
      storePathCommitLog=/home/rocketmq-all-4.4.0-bin-release/store/commitlog
      #消费队列存储路径存储路径
      storePathConsumeQueue=/home/rocketmq-all-4.4.0-bin-release/store/consumequeue
      #消息索引存储路径
      storePathIndex=/home/rocketmq-all-4.4.0-bin-release/store/index
      #checkpoint 文件存储路径
      storeCheckpoint=/home/rocketmq-all-4.4.0-bin-release/store/checkpoint
      #abort 文件存储路径
      abortFile=/home/rocketmq-all-4.4.0-bin-release/store/abort
      #限制的消息大小,64KB
      maxMessageSize=65536
      #flushCommitLogLeastPages=4
      #flushConsumeQueueLeastPages=2
      #flushCommitLogThoroughInterval=10000
      #flushConsumeQueueThoroughInterval=60000
      #Broker 的角色
      #- ASYNC_MASTER 异步复制Master
      #- SYNC_MASTER 同步双写Master
      #- SLAVE
      brokerRole=SLAVE
      #刷盘方式
      #- ASYNC_FLUSH 异步刷盘
      #- SYNC_FLUSH 同步刷盘
      # 主节点配置成同步刷盘,从节点配置成异步刷盘
      flushDiskType=ASYNC_FLUSH
      #checkTransactionMessageEnable=false
      #发消息线程池数量
      #sendMessageThreadPoolNums=128
      #拉消息线程池数量
      #pullMessageThreadPoolNums=128
      brokerIP1=192.168.1.4
      #允许从服务器落户的最大偏移字节数,默认为256M。超过该值则表示该Slave不可用
      haSlaveFallbehindMax=268435456
      
    4. broker_s_2

      其他同broker_s_1

      1
      2
      3
      
      brokerName=broker-2
      #Broker 对外服务的监听端口
      listenPort=13911
      
  8. 重启6台机器

    1
    
    $ dcp -f 2n_2m_2s.yaml restart
    
  9. check

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    # 查看namesrv_1日志
    $ tail -20f namesrv_1/log/namesrv.log
    2020-11-25 20:13:45 INFO main - The Name Server boot success. serializeType=JSON
    # 查看broker_m_1日志
    $ tail -20f broker_m_1/log/broker.log
    2020-11-25 20:13:48 INFO main - The broker[d7363b30979e, 183.40.0.4:10911] boot success. serializeType=JSON
    # 查看broker_s_2日志
    $ tail -20f broker_s_2/log/broker.log
    2020-11-25 20:13:49 INFO main - The broker[72a846a7d3e0, 183.40.0.7:10911] boot success. serializeType=JSON
    2020-11-25 20:13:58 INFO BrokerControllerScheduledThread1 - dispatch behind commit log 0 bytes
    2020-11-25 20:13:58 INFO BrokerControllerScheduledThread1 - Slave fall behind master: 0 bytes
    2020-11-25 20:14:58 INFO BrokerControllerScheduledThread1 - dispatch behind commit log 0 bytes
    2020-11-25 20:14:58 INFO BrokerControllerScheduledThread1 - Slave fall behind master: 0 bytes
    2020-11-25 20:15:58 INFO BrokerControllerScheduledThread1 - dispatch behind commit log 0 bytes
    2020-11-25 20:15:58 INFO BrokerControllerScheduledThread1 - Slave fall behind master: 0 bytes
    2020-11-25 20:16:58 INFO BrokerControllerScheduledThread1 - dispatch behind commit log 0 bytes
    2020-11-25 20:16:58 INFO BrokerControllerScheduledThread1 - Slave fall behind master: 0 bytes
    

Mqadmin管理工具

mqadmin管理工具

  1. 执行命令方法:./mqadmin {command} {args}

rocketmq-console

rocketmq-console

rocketmq-console 中文文档

How to install with docker

官方文档有误,下载下面这个,100K+的downloads

styletang/rocketmq-console-ng

下载

1
2
# 下载
docker pull styletang/rocketmq-console-ng:1.0.0

配置到docker-compose中,让rocketmq-console和namesrv在一个网段

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    rmqconsole:
        image: styletang/rocketmq-console-ng:1.0.0
        container_name: rmqconsole
        ports: 
            - 8090:8080
        networks: 
            rocketmq: 
                ipv4_address: 183.40.0.8 # 设置静态ipv4地址
        environment:
          JAVA_OPTS: "-Drocketmq.namesrv.addr=183.40.0.2:9876;183.40.0.3:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"
        depends_on:
            - namesrv_1
            - namesrv_2

查看ip

1
2
3
4
5
6
7
8
$ docker_ip
/broker_s_1 - 183.40.0.6
/broker_s_2 - 183.40.0.7
/broker_m_2 - 183.40.0.5
/broker_m_1 - 183.40.0.4
/rmqconsole - 183.40.0.8
/namesrv_2 - 183.40.0.3
/namesrv_1 - 183.40.0.2

访问:http://localhost:8090/

http://img.cana.space/picStore/20201125220514.png

可以看到我们的两台namesrv已经被监控到了。

再看集群

http://img.cana.space/picStore/20201125222958.png

测试发送消息,随便登录一台broker,进入到bin目录,编辑tools.sh,配置NAMESRV_ADDR,配置如下:

1
2
3
vim tools.sh
# 在export JAVA_HOME上面添加如下这段代码
export NAMESRV_ADDR=183.40.0.2:9876;183.40.0.3:9876

发送消息

1
[root@eb83844a97a8 bin]# sh tools.sh org.apache.rocketmq.example.quickstart.Producer

成功的话会看到哗哗哗的日志,因为这个类会发送1000条消息到TopicTest这个Topic下。

接受消息

1
[root@eb83844a97a8 bin]# ./tools.sh org.apache.rocketmq.example.quickstart.Consumer

查看控制台

http://img.cana.space/picStore/20201125224305.png

可以新增测试主题,指定了集群就不用再指定broker了,反之指定了broker就不用再指定集群

根据消息id查询消息信息

http://img.cana.space/picStore/20201125224710.png


更新:

1.0.1版本有消息轨迹功能,建议升级到1.0.1,最新版就是1.0.1,但是查看tag发现最新版是1.0.0,自己搞一个

20201125225439

RocketMQ有一个对其扩展的开源项目incubator-rocketmq-externals,这个项目中有一个子模块叫rocketmq-console,这个便是管理控制台项目了,先将incubator-rocketmq-externals拉到本地,因为我们需要自己对rocketmq-console进行编译打包运行。

先清理一波原镜像

1
2
3
4
5
6
# 暂停容器
$ docker stop 8e
# 删除容器
$ dcp -f 2n_2m_2s.yaml rm -v rmqconsole
# 删除镜像
$ docker rmi 7d

下载打包:

1
2
3
4
5
6
7
8
git clone https://github.com/apache/rocketmq-externals
cd rocketmq-console
mvn clean package -Dmaven.test.skip=true docker:build
$ docker images
REPOSITORY                                                 TAG                 IMAGE ID            CREATED             SIZE
styletang/rocketmq-console-ng                              1.0.1               6111bcf5d13a        8 seconds ago       710MB
styletang/rocketmq-console-ng                              latest              6111bcf5d13a        8 seconds ago       710MB
# 是真的大。。。

坑是真的多,1.0.1改成了rocketmq.config.namesrvAddr,使用docker 环境变量也不生效,直接在springboot项目里改application.properties成功:

1
rocketmq.config.namesrvAddr=192.168.25.135:9876;192.168.25.138:9876

修改完后重新打包构建镜像

1
mvn clean package -Dmaven.test.skip=true docker:build

清理原来的console镜像,刷新

1
$ dcp -f 2n_2m_2s.yaml up -d

重新打开,记得强刷,http://localhost:8090/ ,现在可以看到消息轨迹了

http://img.cana.space/picStore/20201125234337.png

登录到89,使用tools.sh发送消息,再消费消息

1
2
3
4
5
6
7
vim tools.sh
# 在export JAVA_HOME上面添加如下这段代码
export NAMESRV_ADDR=183.40.0.2:9876;183.40.0.3:9876
# 发送消息,默认1000条
sh tools.sh org.apache.rocketmq.example.quickstart.Producer
# 消费消息
./tools.sh org.apache.rocketmq.example.quickstart.Consumer

查看集群情况

http://img.cana.space/picStore/20201125234630.png

坑1

生产者发送消息报:

1
Exception in thread "main" org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout

解决

在broker配置文件中加上

1
2
#pullMessageThreadPoolNums=128
brokerIP1=192.168.1.4

暴露10911端口应该是宿主机做的工作,如果不配置宿主机ip会变成容器暴露10911端口,像下面这样

http://img.cana.space/picStore/20201125234630.png

改过之后:

http://img.cana.space/picStore/20201126012437.png

坑2

启动控制台报:

1
2
org.apache.rocketmq.client.exception.MQClientException: CODE: 17  DESC: No topic route info in name server for the topic: %RETRY%FILTERSRV_CONSUMER
See http://rocketmq.apache.org/docs/faq/ for further details.

要么在控制台新建 %RETRY%FILTERSRV_CONSUMER 这个topic,要么设置自动创建topic,这里为了方便直接在控制台新建了,可以在开发环境设置自动创建topic,生产环境得禁止。

1
$ sh mqbroker autoCreateTopicEnable=true

手动建

http://img.cana.space/picStore/20201126013926.png

在控制台看到成功插入一条记录

http://img.cana.space/picStore/20201126014050.png

查看console日志,不再报这个错误了

坑3

console进行 mvn clean package -Dmaven.test.skip=true docker:build时需要先在boot项目的配置文件application.properties里面设置

1
rocketmq.config.namesrvAddr=192.168.25.135:9876;192.168.25.138:9876

原先为空,启动会报xxx<null>xxx

坑4

容器需要对外暴露服务,需要设置brokerIP1=192.168.1.4,broker对外暴露的监听端口就是192.168.1.4:xxx

双主双从4个broker监听端口不能一样,需要分别设置成10909/11909/12909/13909

remotingServer和fastRemotingServer默认规则分别是broker的listenPort+1-2

这个需要分别在broker.properties和docker-compose.yaml里设置好。

http://img.cana.space/picStore/20201126154420.png