玩转RabbitMQ之五:运行与管理MQ

一、节点的概念

  在玩转RabbitMQ之一:RabbitMQ的安装中,曾简单解释过Erlang跟RabbitMQ之间的关系,我们用JVM跟Java之间的关系做了类比。

  如果你对分布式集群的概念有点理解的话,你可能经常听到节点这个词,每台服务器都可以看成是一个节点,多个节点连接在一起组成了集群,对外提供服务时好像一台服务器一样。分布式的流行是因为可以根据应用程序请求压力和容量需求,动态地为集群增加和减少节点,这种弹性的集群节点管理为系统性能的扩容提供了极大的便利,同时也避免了机器资源的浪费,更重要的是增强了系统的健壮性和残存性,传统的BS模式靠的是单一的服务器节点,一旦这台机器挂掉,整个应用程序就全部挂掉了,分布式集群从理论上说就算100个节点组成的集群有99个挂掉了,只要有一个节点还是正常的它就能够对外提供服务。

  云计算也是在分布式的基础上发展起来的,之前看过一个视频,采访阿里云创始人王坚,他对云计算做了一个很形象的比喻:让计算资源像水龙头供水一样按需使用。这每一滴水,大概就像一个节点一样,一个个节点,组成了计算资源的“水流”。

  扯远了,回到Erlang节点,Erlang是RabbitMQ运行的环境或容器,RabbitMQ是节点上的应用程序,RabbitMQ数据库Mnesia也是运行在Erlang的应用程序,如果只是RabbitMQ应用程序崩溃了,并不会影响节点上的其他应用程序的运行,如果是Erlang节点崩溃了,容器都挂了上面的所有应用程序自然也会都挂掉,一般一个Erlang节点上只会运行一个RabbitMQ应用程序和配合使用的其他应用程序,你可以将一个RabbitMQ应用程序称为一个节点,但需要了解真正意义上的节点时什么含义。

Erlang节点和应用程序

二、节点管理

1、启动节点

  进入服务器上RabbitMQ可执行文件目录,执行下面命令启动节点:

[root@localhost huyihao]# cd /usr/sbin/
[root@localhost sbin]# rabbitmq
rabbitmqadmin     rabbitmqctl       rabbitmq-plugins  rabbitmq-server   
[root@localhost sbin]# rabbitmq-server 

              RabbitMQ 3.6.6. Copyright (C) 2007-2016 Pivotal Software, Inc.
  ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/
  ##  ##
  ##########  Logs: /var/log/rabbitmq/rabbit@localhost.log
  ######  ##        /var/log/rabbitmq/rabbit@localhost-sasl.log
  ##########
              Starting broker...
 completed with 7 plugins.

  可以看到启动的RabbitMQ相关的信息,使用组合键ctrl+c就能关闭节点,这里可以看到默认的节点名为rabbit@localhost,组成规则是nodeName@domain/ip

[root@localhost sbin]# rabbitmq-server 

              RabbitMQ 3.6.6. Copyright (C) 2007-2016 Pivotal Software, Inc.
  ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/
  ##  ##
  ##########  Logs: /var/log/rabbitmq/rabbit@localhost.log
  ######  ##        /var/log/rabbitmq/rabbit@localhost-sasl.log
  ##########
              Starting broker...
 completed with 7 plugins.
^C
Session terminated, killing shell... ...已杀死。
[root@localhost sbin]# Stopping and halting node rabbit@localhost ...
Gracefully halting Erlang VM

  有时你不想让一个终端窗口启动后就被占用了,那么可以选择后台启动节点:

[root@localhost sbin]# rabbitmq-server -detached
Warning: PID file not written; -detached was passed.


2、停止节点

  如果是前台启动的节点,可以用组合键ctrl+c关闭节点,如果是后台呢?需要使用rabbitmqctl工具,对RabbitMQ进行管理时rabbitmqctl能满足大多数需求:

[root@localhost sbin]# rabbitmqctl stop
Stopping and halting node rabbit@localhost ...


3、关闭应用程序而不停止节点

  你可能突发奇想,既然节点上运行了多个应用程序,那么是否能值关闭应用程序而不停止节点,rabbitmqctl可以做到,打印信息明显不同:

[root@localhost sbin]# rabbitmqctl stop_app
Stopping node rabbit@localhost ...


4、日志

  很幸运,顺风顺水成功启动停止的节点,但有的时候节点可能发生故障,输入的命令可能有各种报错,这时候就需要查看日志了,从前台启动节点的打印输出信息可以知道,日志的位置位于/var/log/rabbitmq,我们进入看看:

[root@localhost sbin]# cd /var/log/rabbitmq/
[root@localhost rabbitmq]# ll
总用量 28416
drwxr-xr-x. 2 root     root           6 9月  13 10:50 mnesia
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  16 10:22 rabbit_1.log
-rw-r--r--. 1 rabbitmq rabbitmq   72099 9月  15 23:40 rabbit_1.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  16 10:22 rabbit_1-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq   30953 9月  13 22:11 rabbit_1-sasl.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  16 10:22 rabbit_2.log
-rw-r--r--. 1 rabbitmq rabbitmq   60117 9月  15 23:38 rabbit_2.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  12 20:53 rabbit_2-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  16 10:22 rabbit_3.log
-rw-r--r--. 1 rabbitmq rabbitmq   10545 9月  13 22:11 rabbit_3.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  12 21:08 rabbit_3-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  26 20:28 rabbit_a.log
-rw-r--r--. 1 rabbitmq rabbitmq 3413413 9月  16 22:47 rabbit_a.log-20180926
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  26 20:28 rabbit_a-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq 5226269 9月  16 19:31 rabbit_a-sasl.log-20180926
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  26 20:28 rabbit_b.log
-rw-r--r--. 1 rabbitmq rabbitmq 1789380 9月  16 22:48 rabbit_b.log-20180926
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  26 20:28 rabbit_b-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq 5022542 9月  16 22:48 rabbit_b-sasl.log-20180926
-rw-r--r--. 1 rabbitmq rabbitmq  585944 9月  28 21:16 rabbit@localhost.log
-rw-r--r--. 1 rabbitmq rabbitmq     910 8月  15 08:02 rabbit@localhost.log-20180819.gz
-rw-r--r--. 1 rabbitmq rabbitmq    2278 8月  26 19:31 rabbit@localhost.log-20180826.gz
-rw-r--r--. 1 rabbitmq rabbitmq     656 9月   1 15:09 rabbit@localhost.log-20180902.gz
-rw-r--r--. 1 rabbitmq rabbitmq    1316 9月   2 23:36 rabbit@localhost.log-20180909.gz
-rw-r--r--. 1 rabbitmq rabbitmq    2729 9月  13 21:32 rabbit@localhost.log-20180916.gz
-rw-r--r--. 1 rabbitmq rabbitmq 7209837 9月  17 21:13 rabbit@localhost.log-20180926
-rw-r--r--. 1 rabbitmq rabbitmq 1594920 9月  28 21:16 rabbit@localhost-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq  289934 9月  17 19:59 rabbit@localhost-sasl.log-20180917.gz
-rw-r--r--. 1 rabbitmq rabbitmq 3699981 9月  17 21:13 rabbit@localhost-sasl.log-20180926
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  16 10:22 rabbit.log
-rw-r--r--. 1 rabbitmq rabbitmq   38817 9月  15 23:41 rabbit.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq       0 9月  16 10:22 rabbit-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq     802 9月  13 11:11 rabbit-sasl.log-20180916

  可以看到目录下有很多文件,还有一个mnesia的目录,这是RabbitMQ的数据库数据存储的目录,除了rabbit@localhost.log,还看到很多前缀一样的文件,后面带了日期,很明显这是对每日日志的备份,打印最近的20行rabbit@localhost.log看看:

[root@localhost rabbitmq]# tail -n 20 rabbit@localhost.log
     {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]}

=INFO REPORT==== 28-Sep-2018::21:16:22 ===
Server startup complete; 7 plugins started.
 * rabbitmq_management
 * rabbitmq_shovel
 * amqp_client
 * rabbitmq_web_dispatch
 * webmachine
 * mochiweb
 * rabbitmq_management_agent

=INFO REPORT==== 28-Sep-2018::21:16:25 ===
Stopping RabbitMQ

=INFO REPORT==== 28-Sep-2018::21:16:25 ===
stopped TCP Listener on [::]:5672

=INFO REPORT==== 28-Sep-2018::21:16:26 ===
Stopped RabbitMQ application

  可以看到RabbitMQ的命令日志,上面那一块是启动了一些插件,下面关闭了RabbitMQ,断开与5672端口的链接,最后停止RabbitMQ应用程序,从这里可以知道RabbitMQ默认的端口是5672,如果执行命令时发生报错,那么也可以在RabbitMQ日志里找到相应的日志。

三、RabbitMQ配置

  RabbitMQ默认配置文件的目录位于/etc/rabbitmq,在该目录下可以看到两个配置文件:

[root@localhost rabbitmq]# ll
总用量 8
-rw-r--r--. 1 root root   51 9月  16 22:58 enabled_plugins
-rw-r--r--. 1 root root 1752 9月  16 19:30 rabbitmq.config

  enabled_plugins看名字就知道是配置要启用哪些RabbitMQ插件,有许多常用的插件跟RabbitMQ一起打包安装比如管理控制台rabbitmq_management,每个插件都有一个对应ez文件,默认位于/usr/lib/rabbitmq/lib/rabbitmq_server-3.6.6/plugins,从配置的内容看启用了三个插件。

[root@localhost rabbitmq]# cat enabled_plugins 
[amqp_client,rabbitmq_management,rabbitmq_shovel].

  rabbitmq.config是RabbitMQ的系统配置文件,如果没有这个文件,则可自行创建,打印文件内容,看看配置了些什么东西。

[root@localhost rabbitmq]# cat rabbitmq.config 
[
   {mnesia, [{dump_log_write_threshold, 1000}]},
   {rabbit, [{vm_memory_high_watermark, 0.4}]},
]

  配置文件的格式最外层是中括号(数组),每个配置元素都以花括号表示,每个元素的值又可能是一个数组,实际上数组允许多重嵌套,可以看到第一个配置mnesia数据库的配置,配置了一个dump_log_write_threshold的配置项,值为1000,这个参数表示将仅限追加的日志内容刷出/转储到真是数据库文件的频度,为什么不产生一条数据就马上存储到数据库文件呢?而是每满1000条就存一次,这样做的目的是为了降低I/O(读写)的次数,避免对系统性能造成影响,当然只有持久化消息才需要将数据持久化(存储到数据库文件中)。

  vm_memory_high_watermark为控制RabbitMQ允许消耗的内存最大比例,这里设为0.4即最多允许MQ消耗服务器40%的内存。

  Mnesia和Rabbit配置项罗列如下:

(1)Mnesia配置选项
配置项 默认值 描述
dump_log_write_threshold(整型) 100 将仅限追加的日志内容刷出/转储至真实数据库文件的频度。它明确制定了在转储操作发生前,必须有多少个条目存储在日志中。设置更高的数值将减少I/O负载并增加持久化消息的性能
(2)Rabbit配置选项
配置项 默认值 描述
tcp_listeners({"ip地址":端口号} 数组) [{"0.0.0.0", 5672},] 定义了RabbitMQ应该监听的非SSL加密通信的IP地址和端口
ssl_listeners({"ip地址":端口号} 数组) 定义了RabbitMQ应该监听的SSL加密通信的IP地址和端口
ssl_options({"键":值} 数组) 指定SSL相关的选项。有效的选项有cacertfile(CA证书文件)、certfile(服务器证书文件)、keyfile(服务器密钥文件)和fail_if_no_peer_cert(需要客户端安装有效证书:True/False)
vm_memory_high_watermark(十进制百分数) 0.4 控制RabbitMQ允许消耗的内存。它以十进制数值的形式明确了Rabbit允许使用的安装内存百分比(0.4=40%)
msg_store_file_size_limit(整型:字节) 16777216 RabbitMQ垃圾收集存储内容之前,消息存储数据库的最大大小
queue_index_max_journal_entries 262144 在转储到消息存储数据库并提交之前,消息存储日志里的最大条目数

  除了这些配置,RabbitMQ的很多插件也是允许在配置文件中做配置并随启动生效的,具体的配置项要看使用的插件。

四、权限管理

  RabbitMQ的权限主要针对用户而言,有点类似Linux的文件访问权限,RabbitMQ的用户权限由三部分组成:读、写、配置,如下表所示:

AMQP命令 配置
exchange.declare exchange
exchange.delete exchange
queue.declare queue
queue.delete queue
queue.bind queue exchange
basic.publish exchange
basic.get queue
basic.consume queue
queue.purge queue

  交换器、队列的声明和删除属于配置权限;队列的绑定需要有对队列的写权限和对交换器的读权限;消息发布到交换器上需要对交换器的写权限;消息的获取和消费需要队列的读权限;队列的清空也属于读权限。

  权限管理可以对单个用户在不同的vhost上设置不同的权限,不同的vhost上运行着不同的应用程序,达到对用户为不同的应用程序设置不同级别的权限的目的,如下图所示:

RabbitMQ权限工作原理:用户可以为连接到RabbitMQ主机的应用程序设置不同级别的权限(读、写、配置)

1、用户管理

  要管理用户权限先得有用户,RabbitMQ默认的用户是guest,密码guest,我们使用rabbitmqctl来操作管理RabbitMQ。

  查看MQ中的用户列表:

[root@localhost huyihao]# rabbitmqctl list_users
Listing users ...
monitor [administrator]
guest   [administrator]

  添加用户(用户名:huyihao,密码:666):

[root@localhost huyihao]# rabbitmqctl add_user huyihao 666
Creating user "huyihao" ...

  重新看一下用户列表:

[root@localhost huyihao]# rabbitmqctl list_users
Listing users ...
monitor [administrator]
huyihao []
guest   [administrator]

  删除用户:

[root@localhost huyihao]# rabbitmqctl delete_user huyihao
Deleting user "huyihao" ...

  哪一天你把用户密码忘了,需要重置:

[root@localhost huyihao]# rabbitmqctl add_user huyihao 666
Creating user "huyihao" ...
[root@localhost huyihao]# rabbitmqctl change_password huyihao 777
Changing password for user "huyihao" ...


2、虚拟主机管理与用户授权

  RabbitMQ默认的虚拟主机是"/",查看系统中所有的vhost:

[root@localhost huyihao]# rabbitmqctl list_vhosts
Listing vhosts ...
/

  假设现在你有一个应用要使用mq,为了跟其他原有的应用区分开互相隔离,需要创建一个新的vhost:

[root@localhost huyihao]# rabbitmqctl add_vhost newapp
Creating vhost "newapp" ...

  既然每个用户对每个vhost的权限都是独立的,你可能好奇有没有默认的权限之类的东西,使用下面的命令来查看用户对每个vhosts的权限列表:

[root@localhost huyihao]# rabbitmqctl list_user_permissions huyihao
Listing permissions for user "huyihao" ...
# 默认是空的,说明新建的用户不会对任何一个vhost(包括默认vhost)有任何操作权限!

  当MQ管理员定期想检查某个应用对应的vhosts对不同用户的授权情况如何时,可使用以下命令:

[root@localhost huyihao]# rabbitmqctl list_permissions -p newapp
Listing permissions in vhost "newapp" ...
# 默认是空的,说明新建的用户不会对任何一个用户(包括guest)授予任何权限!

  现在我们想让新建的用户huyihao对虚拟主机newapp授予读写配置的权限,可使用如下命令:

[root@localhost huyihao]# rabbitmqctl set_permissions -p newapp huyihao ".*" ".*" ".*"
Setting permissions for user "huyihao" in vhost "newapp" ...
[root@localhost huyihao]# rabbitmqctl list_permissions -p newapp
Listing permissions in vhost "newapp" ...
huyihao .*  .*  .*
[root@localhost huyihao]# rabbitmqctl list_user_permissions huyihao
Listing permissions for user "huyihao" ...
newapp  .*  .*  .*
# 授权命令的格式:rabbitmqctl set_permissions -p [vhost] [user] [配置权限] [读权限] [写权限]
# 授权正则表达式:
# (1)".*": 匹配任何队列和交换器
# (2)"xx.*": 只匹配名字以xx开头的交换器和队列
# (3)"": 不匹配任何队列和交换器(就是没有权限)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容

  • 什么叫消息队列? 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复...
    Agile_dev阅读 2,371评论 0 24
  • 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时...
    Java机械师阅读 547评论 0 2
  • 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时...
    Johnson_zx阅读 1,108评论 0 5
  • 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时...
    预流阅读 584,637评论 51 786
  • 传我命令,诛杀轩辕家族所有血脉一 太渊国国公齐震,这一天正在神坛前偷听太渊国国王的谈话,这神坛有个功能就是能够随着...
    一见平天下阅读 250评论 0 1