1. 查看RabbitMQ基本信息

rabbitmqctl status  #单节点MQ状态

rabbitmqctl report  #集群状态,包括各个节点MQ状态、镜像队列状态等

rabbiemq service 端口怎么查 rabbitmq 查看状态_erlang

  memory total是MQ进程实际占用内存大小,vm_memory_limit是限制MQ进程使用的内存大小。当memory total > vm_memory_limit * vm_memory_high_watermark_paging_ratio时,触发流控(flow control),生产速度下降;当memory total > vm_memory_limit时,触发阻塞(block),生产速度停止。

  发生故障时,建议先查看RabbitMQ集群状态,保存日志,以便分析定位。



2. 查看RabbitMQ运行状态

  由于RabbitMQ使用erlang -detached方式后台运行,在机器上可以通过remote shell直接连上erlang shell,查看运行状态。

erl -sname test -remsh rmq@rmq -setcookie XXXXXXXXXXX

  使用etop分析erlang任务。

spawn(fun() -> etop:start([{output, text}, {interval, 5}, {lines, 10}, {sort, msg_q}]) end).

spawn(fun() -> etop:start([{output, text}, {interval, 5}, {lines, 10}, {sort, reductions}]) end).

rabbiemq service 端口怎么查 rabbitmq 查看状态_shell_02

 

  使用process_info查看进程状态。

process_info(pid(0, 291, 0)).

rabbiemq service 端口怎么查 rabbitmq 查看状态_erlang_03

 

rabbiemq service 端口怎么查 rabbitmq 查看状态_erlang_04


rabbiemq service 端口怎么查 rabbitmq 查看状态_数据_05

  正常情况下进程邮箱(MsgQ)是一个很小的值。当MsgQ值较大时,可能是进程阻塞(gen_server等),或者是收到了无法匹配的消息(selective receive),此时可以查看进程状态定位出错模块和消息类型。


3. 镜像队列状态与同步

rabbitmqctl stop命令并等待程序停止,异常退出包括进程crash、kill、机器宕机等。

  镜像队列同步状态可以在web UI查看,也可以通过以下命令。

rabbitmqctl list_queues name slave_pids synchronised_slave_pids

rabbiemq service 端口怎么查 rabbitmq 查看状态_数据_06

 

  当集群中存在已同步节点时,master退出不影响正常服务,集群将一个已同步slave节点提升为master。

  当集群中没有已同步节点时,master正常退出,队列将不可服务(DOWN状态),待master重新启动后,服务恢复(确保了未同步数据的可靠性);master异常退出时,集群提升最老的slave为新master服务继续,原master未同步数据将丢失(原master异常退出后,数据处于未知状态,该处理确保了可用性)。

  对于镜像队列,建议至少保持一个同步节点。

  在集群没有已同步节点时,要重启master,需先同步数据。

rabbitmqctl sync_queue name

队列处于不可服务状态(DOWN),如果原master磁盘文件无法备份,只能删除并重建队列(数据完全丢失)。

rabbitmqctl forget_cluster_node old_master@old_master  #自动删除old_master队列

rabbitmqctl forget_cluster_node old_master@old_master --offline  #节点已退出时调用

  若能够备份磁盘文件,则可以通过文件恢复原队列数据。


4. 数据恢复

  备份RABBITMQ_MNESIA_DIR(/data/rabbitmq/mnesia/node_name)目录,复制到一个新节点上。修改新节点hostname(包括RABBITMQ_NODENAME、/etc/hosts等)、erlang cookie(/var/lib/rabbitmq/.erlang.cookie)保持与旧节点一致。

  原节点不属于镜像队列,直接启动新节点即可。

  原节点属于镜像队列,集群中无其他节点运行时,可以只启动新节点,恢复原节点数据。

rabbitmqctl force_boot  #忽略集群master,直接启动当前节点

/etc/init.d/rabbitmq-server start  #启动后仅能操作old_master队列,其他队列DOWN

  原节点属于镜像队列,集群中有其他节点运行时,直接启动新节点,新节点加入集群,已中断服务的队列恢复正常(无数据丢失)。


5. 替换机器

  集群添加节点时:先加入(join_cluster),后oss扩容。加入集群操作:

rabbitmqctl stop_app

rabbitmqctl join_cluster  name@node

rabbitmqctl start_app

  集群删除节点时:先oss缩容,后退出(reset)。退出集群操作:

rabbitmqctl stop_app

rabbitmqctl reset

rabbitmqctl start_app

  原集群存在A、B两个节点,将B节点替换为C节点流程:

a.修改C节点hostname,haproxy配置;修改A、C节点/etc/hosts,保持一致

b.启动C节点haproxy和RabbitMQ,加入A节点集群(rabbitmqctl join_cluster A@A)

c.修改A节点haproxy配置,并重启haproxy

d.在OSS将C节点扩容到集群

e.待集群同步后,在OSS将B节点从集群中缩容

f.在B节点上,退出集群(rabbitmqctl reset)

g.修改A、C节点/etc/hosts,去掉B节点(可选)

  修改hostname:

hostname "$NODE_NAME"  #临时修改hostname,重启后失效

echo "$NODE_NAME" > /proc/sys/kernel/hostname  #永久修改hostname,重启后仍有效

sed -i '/HOSTNAME/'d /etc/sysconfig/network

echo "HOSTNAME=$NODE_NAME" >> /etc/sysconfig/network

sed -i '/RABBITMQ_NODENAME/'d /etc/rabbitmq/rabbitmq-env.conf  #rabbit nodename

echo "RABBITMQ_NODENAME=$NODE_NAME" >> /etc/rabbitmq/rabbitmq-env.conf

  修改C节点/etc/hosts时,当A节点是master时,C节点/etc/hosts不用配置B;当A节点不是master时,C节点需要配置B。建议直接将B加入/etc/hosts.


6. 数据迁移

  使用dynamic shovel将一个队列数据迁移到另一个队列。

rabbitmqctl set_parameter shovel my-shovel 
              '{"src-uri": "amqp://", "src-queue": "my-queue", \
                "dest-uri": "amqp://remote-server", "dest-queue": "another-queue"}'