玩转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
rabbitmqadminrabbitmqctlrabbitmq-pluginsrabbitmq-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 rootroot6 9月13 10:50 mnesia
-rw-r--r--. 1 rabbitmq rabbitmq0 9月16 10:22 rabbit_1.log
-rw-r--r--. 1 rabbitmq rabbitmq72099 9月15 23:40 rabbit_1.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq0 9月16 10:22 rabbit_1-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq30953 9月13 22:11 rabbit_1-sasl.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq0 9月16 10:22 rabbit_2.log
-rw-r--r--. 1 rabbitmq rabbitmq60117 9月15 23:38 rabbit_2.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq0 9月12 20:53 rabbit_2-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq0 9月16 10:22 rabbit_3.log
-rw-r--r--. 1 rabbitmq rabbitmq10545 9月13 22:11 rabbit_3.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq0 9月12 21:08 rabbit_3-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq0 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 rabbitmq0 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 rabbitmq0 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 rabbitmq0 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 rabbitmq585944 9月28 21:16 rabbit@localhost.log
-rw-r--r--. 1 rabbitmq rabbitmq910 8月15 08:02 rabbit@localhost.log-20180819.gz
-rw-r--r--. 1 rabbitmq rabbitmq2278 8月26 19:31 rabbit@localhost.log-20180826.gz
-rw-r--r--. 1 rabbitmq rabbitmq656 9月1 15:09 rabbit@localhost.log-20180902.gz
-rw-r--r--. 1 rabbitmq rabbitmq1316 9月2 23:36 rabbit@localhost.log-20180909.gz
-rw-r--r--. 1 rabbitmq rabbitmq2729 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 rabbitmq289934 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 rabbitmq0 9月16 10:22 rabbit.log
-rw-r--r--. 1 rabbitmq rabbitmq38817 9月15 23:41 rabbit.log-20180916
-rw-r--r--. 1 rabbitmq rabbitmq0 9月16 10:22 rabbit-sasl.log
-rw-r--r--. 1 rabbitmq rabbitmq802 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 root51 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的权限主要针对用户而言,有点类似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)授予任何权限!
【玩转RabbitMQ之五(运行与管理MQ)】??现在我们想让新建的用户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)"": 不匹配任何队列和交换器(就是没有权限)
推荐阅读
- 【年终激励系列】之五(年终奖如何与考核紧密相连)
- 炒股知识(超级短线操作的秘籍|炒股知识:超级短线操作的秘籍 玩转股市)
- 玩转Micro:bit(04):电子宠物
- 何以解忧,企业信息化、数字化选型焦虑之五·系统安全隐患大
- 要玩转这个星际争霸II开源AI,你只需要i5+GTX1050
- 销售与神经科学
- 成为有趣的人,轻松玩转人生!
- 带孩子玩转东京,你需要这份最全面的攻略
- python|oeasy教您玩转python - 007 - # 字符本质
- 基于rabbitmq实现的延时队列(golang版)