配置与管理RabbitMQ
管理RabbitMQ
RabbitMQ 默认有一个根VHOST 当然一般情况下我们都会创建属于某个应用程序的vhost 去方便管理。在个节点当中vhost 与 vhost 之间是互相隔离的,所以在多个不同的vhost当中可以创建相同名称的 交换器(exchange) 队列(queue)。这个概念就像是数据库一样,mysql当中有个多个不同的数据库,多个数据库当中可以使用相同的表名的概念一样。
接下来我们就来开始写一下如何创建vhost~
创建Vhost
MacBook-Pro:rabbitmq Tony$ /usr/local/sbin/rabbitmqctl add_vhost APP_A Creating vhost "APP_A" ...
删除Vhost
MacBook-Pro:rabbitmq Tony$ /usr/local/sbin/rabbitmqctl delete_vhost APP_A Deleting vhost "APP_A" ...
查看节点上的Vhost
MacBook-Pro:rabbitmq Tony$ /usr/local/sbin/rabbitmqctl list_vhosts Listing vhosts ... / APP_A APP_B
JAVA客户端中链接相应的vhost
ConnectionFactory factory = new ConnectionFactory(); factory.setHost("127.0.0.1"); //服务器地址 factory.setUsername("guest"); //默认用户名 factory.setPassword("guest"); //默认密码 factory.setVirtualHost("APP_A"); //vhost名称 factory.setPort(5672); //默认端口
启动和停止RabbitMQ RabbitMQ启动的方式比较简单,但是关闭会有几种方式去个关闭,而且关闭的情况各有不同。
启动RabbitMQ
MacBook-Pro:~ Tony$ /usr/local/sbin/rabbitmq-server RabbitMQ 3.5.6. Copyright (C) 2007-2015 Pivotal Software, Inc. ## ## Licensed under the MPL. See http://www.rabbitmq.com/ ## ## ########## Logs: /usr/local/var/log/rabbitmq/[email protected] ###### ## /usr/local/var/log/rabbitmq/[email protected] ########## Starting broker... completed with 10 plugins.
我不建议,直接在这里使用ctrl+C的方法直接结束应用程序,我这里推荐以下方式去关闭RabbitMQ。使用这种方式有效干净关闭,并且保护好持久化的队列。
关闭RabbitMQ
MacBook-Pro:rabbitmq Tony$ /usr/local/sbin/rabbitmqctl stop Stopping and halting node rabbit@localhost ...
当然也可以使用 -n rabbit@[hostname]来关闭其他远程节点。这个会在介绍群集的时候在贴出代码
查看RabbitMQ 状态
MacBook-Pro:lib Tony$ /usr/local/sbin/rabbitmqctl status Status of node rabbit@localhost ... [{pid,10780}, {running_applications, [{rabbitmq_management_visualiser,"RabbitMQ Visualiser","3.5.6"}, {rabbitmq_management,"RabbitMQ Management Console","3.5.6"}, {rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.5.6"}, {webmachine,"webmachine","1.10.3-rmq3.5.6-gite9359c7"}, {mochiweb,"MochiMedia Web Server","2.7.0-rmq3.5.6-git680dba8"}, {rabbitmq_mqtt,"RabbitMQ MQTT Adapter","3.5.6"}, {rabbitmq_stomp,"Embedded Rabbit Stomp Adapter","3.5.6"}, {rabbitmq_management_agent,"RabbitMQ Management Agent","3.5.6"}, {rabbitmq_amqp1_0,"AMQP 1.0 support for RabbitMQ","3.5.6"}, {rabbit,"RabbitMQ","3.5.6"}, {os_mon,"CPO CXC 138 46","2.3.1"}, {inets,"INETS CXC 138 49","5.10.6"}, {mnesia,"MNESIA CXC 138 12","4.12.5"}, {amqp_client,"RabbitMQ AMQP Client","3.5.6"}, {xmerl,"XML parser","1.3.7"}, {sasl,"SASL CXC 138 11","2.4.1"}, {stdlib,"ERTS CXC 138 10","2.4"}, {kernel,"ERTS CXC 138 10","3.2"}]}, {os,{unix,darwin}}, {erlang_version, "Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:64] [hipe] [kernel-poll:true]\n"}, {memory, [{total,43180016}, {connection_readers,0}, {connection_writers,0}, {connection_channels,0}, {connection_other,5616}, {queue_procs,19712}, {queue_slave_procs,0}, {plugins,868704}, {other_proc,13887864}, {mnesia,72792}, {mgmt_db,234672}, {msg_index,47824}, {other_ets,1275216}, {binary,19872}, {code,20760734}, {atom,711569}, {other_system,5275441}]}, {alarms,[]}, {listeners, [{clustering,25672,"::"}, {amqp,5672,"127.0.0.1"}, {stomp,61613,"::"}, {mqtt,1883,"::"}]}, {vm_memory_high_watermark,0.4}, {vm_memory_limit,1401384140}, {disk_free_limit,50000000}, {disk_free,8082620416}, {file_descriptors, [{total_limit,156},{total_used,5},{sockets_limit,138},{sockets_used,3}]}, {processes,[{limit,1048576},{used,198}]}, {run_queue,0}, {uptime,8267}]
再看看 RabbitMQ的配置文件
首先 看看 rabbitmq-env.conf 由于本人也没有碰过 rabbitmq-env.conf 这个文件所以我也 翻了一下官网,看看这个文件是怎么一回事,因为在参考的学习的书本 rabbitmq in action 中的管理rabbit 的章节当中,并没有提及到 rabbitmq-env.conf 文件 只有提及 rabbitma.config 。以下是官网对 rabbitmq-env.conf 文件的介绍 我这里就引用一下。
Name
rabbitmq-env.conf — default settings for RabbitMQ AMQP server
Description
/etc/rabbitmq/rabbitmq-env.conf contains variable settings that override the defaults built in to the RabbitMQ startup scripts.
The file is interpreted【解析】 by the system shell, and so should consist of a sequence【线性】 of shell environment【环境】 variable【变量】 definitions【定义】. Normal shell syntax【语法】 is permitted (since the file is sourced using the shell “.” operator), including line comments starting with “#”.
In order of preference【偏好】, the startup scripts get their values from the environment, from /etc/rabbitmq/rabbitmq-env.conf and finally from the built-in default values. For example, for the RABBITMQ_NODENAME setting,
RABBITMQ_NODENAME
from the environment is checked first. If it is absent【缺失】 or equal to the empty string, then
NODENAME
from /etc/rabbitmq/rabbitmq-env.conf is checked. If it is also absent or set equal to the empty string then the default value from the startup script is used.
The variable names in /etc/rabbitmq/rabbitmq-env.conf are always equal to the environment variable names, with the RABBITMQ_ prefix removed: RABBITMQ_NODE_PORT from the environment becomes NODE_PORT in the /etc/rabbitmq/rabbitmq-env.conf file, etc.
英文跟我一样一般般的看这里,我解释一下:
其实就是说 一般情况下RabbitMQ会有所有环境变量的默认值,他会检查rabbitmq-env.conf这个文件并且如果缺失的参数或者参数为空字符串都会以默认的参数值为准。其实看看官方的英文解析对以后学习很大帮助 我也是努力地去看。
这是官方给出来的example
# I am a complete /etc/rabbitmq/rabbitmq-env.conf file. # Comment lines start with a hash character. # This is a /bin/sh script file - use ordinary envt var syntax NODENAME=hare
但是我在我的MacBook 上寻找了非常多的方法,也无法让配置生效,由于我是用brew命令进行安装的rabbitmq 固然我看了一下文档 不应该在 /etc/rabbitmq/这个目录下去建立这个变量文件,所有我就开始郁闷了。我看了一下文档是这样去写那个位置的:
Generic UNIX - $RABBITMQ_HOME/etc/rabbitmq/rabbitmq-env.conf Debian - /etc/rabbitmq/rabbitmq-env.conf RPM - /etc/rabbitmq/rabbitmq-env.conf Mac OS X (Homebrew) - ${install_prefix}/etc/rabbitmq/rabbitmq-env.conf, the Homebrew prefix is usually /usr/local Windows - %APPDATA%\RabbitMQ\rabbitmq-env-conf.bat
说明配置文件应该在那个目前当中去建立,最终我找到安装的目录:
MacBook-Pro:rabbitmq Tony$ ls -al /usr/local/sbin/ total 48 drwxrwxrwx 8 root wheel 272 10 27 11:16 . drwxr-xr-x 25 root wheel 850 10 27 11:13 .. lrwxr-xr-x 1 Tony wheel 47 10 27 11:16 rabbitmq-defaults -> ../Cellar/rabbitmq/3.5.6/sbin/rabbitmq-defaults lrwxr-xr-x 1 Tony wheel 42 10 27 11:16 rabbitmq-env -> ../Cellar/rabbitmq/3.5.6/sbin/rabbitmq-env lrwxr-xr-x 1 Tony wheel 46 10 27 11:16 rabbitmq-plugins -> ../Cellar/rabbitmq/3.5.6/sbin/rabbitmq-plugins lrwxr-xr-x 1 Tony wheel 45 10 27 11:16 rabbitmq-server -> ../Cellar/rabbitmq/3.5.6/sbin/rabbitmq-server lrwxr-xr-x 1 Tony wheel 43 10 27 11:16 rabbitmqadmin -> ../Cellar/rabbitmq/3.5.6/sbin/rabbitmqadmin lrwxr-xr-x 1 Tony wheel 41 10 27 11:16 rabbitmqctl -> ../Cellar/rabbitmq/3.5.6/sbin/rabbitmqctl
看到这里应该知道他的具体位置了吧~
MacBook-Pro:rabbitmq Tony$ pwd /usr/local/Cellar/rabbitmq/3.5.6/etc/rabbitmq MacBook-Pro:rabbitmq Tony$ ls rabbitmq-env.conf rabbitmq.config.example
然后我建立 rabbitmq-env.conf 之后 是然并卵的~ 我修改了一下端口号,结果还是没有生效。我就差重启电脑了。我目前在按照一台linux的rabbitmq 一会在 LINUX下测试一下。 后面补充一下:在LINUX环境当中测试的确没有任何问题,WHAT THE FUCK 为什么mac os上没有生效~? LINUX的配置文件位置 /etc/rabbitmq/rabbitmq-env.conf
关于环境配置 引用一下 官网:
好再说说rabbitmq.config 哎哟,好没有底气啊。测试不出来,算了吧··· 一会再尝试一下 linux 看看可不可以。
官方提出的最小配置如下:
[ {rabbit, [{tcp_listeners, [5673]}]} ].
其实配置上非常像 JSON 只要仔细观察就能分析出它的编写格式~ 遗憾的是经过测试也是没有生效。之后后面慢慢查看原因了。
后面补充在LINUX 上同样生效,就是不知道为什么mac上不生效。
以下就是官方提供的配置文件位置:
- Generic UNIX - $RABBITMQ_HOME/etc/rabbitmq/
- Debian - /etc/rabbitmq/
- RPM - /etc/rabbitmq/
- Mac OS X (Homebrew) - ${install_prefix}/etc/rabbitmq/, the Homebrew prefix is usually /usr/local
- Windows - %APPDATA%\RabbitMQ\
由于目前我已经在linux之中安装好rabbitMQ,我要抛弃mac 的rabbitMQ了。但是在远程访问rabbitMQ会出错,因为guest用户只能在回环地址中使用,也就是说你只能在本地使用。 然后我给出一下JAVA 远程连接时的错误log
Exception in thread "main" com.rabbitmq.client.PossibleAuthenticationFailureException: Possibly caused by authentication failure at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:355) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:516) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:533) at com.maxfunner.Consumer.createConnectionAndChannel(Consumer.java:35) at com.maxfunner.Consumer.main(Consumer.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; reason: java.net.SocketException: Connection reset at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:67) at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:33) at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:343) at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:216) at com.rabbitmq.client.impl.AMQChannel.rpc(AMQChannel.java:202) at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:347) ... 9 more Caused by: java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:209) at java.net.SocketInputStream.read(SocketInputStream.java:141) at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) at java.io.BufferedInputStream.read(BufferedInputStream.java:265) at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:288) at com.rabbitmq.client.impl.Frame.readFrom(Frame.java:95) at com.rabbitmq.client.impl.SocketFrameHandler.readFrame(SocketFrameHandler.java:131) at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:515)
“guest” user can only connect via localhost
By default, the guest user is prohibited from connecting to the broker remotely; it can only connect over a > loopback interface (i.e. localhost). This applies both to AMQP and to any other protocols enabled via plugins. Any > other users you create will not (by default) be restricted in this way.
如果我们希望在远程的地方使用到guest用户我们可以修改配置
[root@CentOSFrist ~]# vim /etc/rabbitmq/rabbitmq.config
[ {rabbit, [ {tcp_listeners, [5673]}, {loopback_users,[]} ]} ].
重启一下服务就生效了,目前的配置是 rabbit节点上 端口号为5673 loopback用户为空。
[root@centOSFrist ~]# systemctl restart rabbitmq-server.service
启动之后便能够连接到远程的rabbitmq当中 。
先看看如何去创建用户:
MacBook-Pro:sbin Tony$ ./rabbitmqctl add_user tony tonypwd Creating user "tony" ...
成功创建了一个用户名为tony 密码为tonypwd 的用户。
删除用户:
MacBook-Pro:sbin Tony$ ./rabbitmqctl delete_user tony Deleting user "tony" ...
删除一个用户名为tony 的用户
我们可以使用命令去查看用户信息
MacBook-Pro:sbin Tony$ ./rabbitmqctl list_users Listing users ... guest [administrator] tony []
目前有两个用户 一个是 guest 还有就是 tony 然而guest 是 administrator
接下来我们来修改一下密码,注意如果删除了用户连同用户的权限也会同样删除。
MacBook-Pro:sbin Tony$ ./rabbitmqctl change_password tony 123456 Changing password for user "tony" ...
修改了用户名为tony的密码,现在的密码被修改为123456
然后说重点,权限。这个是开发的过程之中用的应该最为常见。
RabbitMQ的权限也是非常容易让人理解的,传统的ACL风格。
读权限:有关消费消息的任何操作,包括 清除 整个队列。
写权限:发布消息
配置权限:队列和交换器的创建和删除。
注意:权限是没有办法跨越vhost的,如果你想某个用户拥有两个vhost的权限,你必须指定两条ACL。
先赋予tony用户对vhost 名称为 APP_A 的全部权限。
[root@centOSFrist ~]# rabbitmqctl set_permissions -p APP_A tony ".*" ".*" ".*" Setting permissions for user "tony" in vhost "APP_A" ...
- -p APP_AP –> 指定权限所对应的vhost,这里所写的vhost为APP_A
- tony –> 跟在vhost 参数后面的是 对应的用户名称 这里所指定的用户名称为tony
- 第一个 “.*” –> 配置权限的正则表达式【最讨厌正则表达式】
- 第二个 “.*” –> 写入权限的正则表达式
- 第三个 “.*” –> 读权限的正则表达式
然后我们可以尝试修改一下tony这个用户的权限
[root@centOSFrist ~]# rabbitmqctl set_permissions -p APP_A tony \ > "tony-.*" "tony-.*" ".*" Setting permissions for user "tony" in vhost "APP_A" ...
tony 用户目前可以对APP_A 这个vhost 配置tony-开头的交换器/队列 同时可以在tony-开头的交换器或者队列发布消息 可以订阅所有消息。
在JAVA 应用程序中测试一下(截取重点代码,以及错误LOG)
ConnectionFactory factory = new ConnectionFactory(); factory.setHost("192.168.0.21"); factory.setUsername("tony"); factory.setPassword("tonypwd"); factory.setVirtualHost("APP_A"); factory.setPort(5673);
创建交换器和队列:
private static final String EXCHANGE_NAME = "MY_EXCHANGE"; this.channel.exchangeDeclare(EXCHANGE_NAME,"direct",false,true,null); //最好也创建一下交换器,反正已经创建也没有关系 this.channel.queueDeclare("QUEUE_A",false,false,true,null); this.channel.queueBind("QUEUE_A",EXCHANGE_NAME,"KEY_A");
由于我目前创建的交换器名称为 MY_EXCHANGE 所以就出现了错误的LOG:
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; reason: {#method<channel.close>(reply-code=403, reply-text=ACCESS_REFUSED - access to exchange 'MY_EXCHANGE' in vhost 'APP_A' refused for user 'tony', class-id=40, method-id=10), null, ""} at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:67) at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:33) at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:343) at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:216) at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:118) ... 10 more
当我修改了所有的交换器和队列的名称为tony-EXCHANGE tony-QUEUE 之后就一切就正常了,我们可以使用命令查看目前某个vhost中的配置:
[root@centOSFrist ~]# rabbitmqctl list_permissions Listing permissions in vhost "/" ... guest .* .* .* [root@centOSFrist ~]# rabbitmqctl list_permissions -p APP_A Listing permissions in vhost "APP_A" ... tony tony-.* tony-.* .*
还可以使用命令查看某个用户的权限:
[root@centOSFrist ~]# rabbitmqctl list_user_permissions tony Listing permissions for user "tony" ... APP_A tony-.* tony-.* .*
删除某一个用户权限如下:
[root@centOSFrist ~]# rabbitmqctl clear_permissions -p APP_A tony Clearing permissions for user "tony" in vhost "APP_A" ... [root@centOSFrist ~]# rabbitmqctl list_user_permissions tony Listing permissions for user "tony" ...
处理针对vhost的使用权限之外还提供,一种角色权限去管理RabbitMQ。
none、management、policymaker、monitoring、administrator
none : 不能访问 management plugin
management : 可以使用AMQP所有功能 列出自己可以通过AMQP登入VHOST 查看自己的vhost中的队列、交换器、绑定 查看和关闭自己的信道(channel) 和 connection 查看自己有关的vhost的“全局”的统计信息和其他用户在这些vhost中的活动。
policymaker : management的所有权限 对自己的vhost所属的policies和parameters 进行增删改查
monitoring : management的所有权限 查看所有vhost 查看节点的数据使用情况 所有vhost的全局的统计信息
administrator : 什么都可以干~
设置用户角色权限:
[root@centOSFrist ~]# rabbitmqctl set_user_tags tony policymaker Setting tags for user "tony" to [policymaker] ... [root@centOSFrist ~]# rabbitmqctl list_users Listing users ... guest [administrator] tony [policymaker]
这个的权限的体现具体会在RabbitMQ的web控制台上面介绍。
查看RabbitMQ的数据信息
列出队列和消息数目
[root@centOSFrist ~]# rabbitmqctl list_queues -p APP_A Listing queues ... tony-QUEUE 0 QUEUE_A 6 ------------ 目前只显示了 队列名称 和对应的 消息总数,除此之外提供一下参数: <queueinfoitem> must be a member of the list [name, durable, auto_delete, arguments, policy, pid, owner_pid, exclusive, exclusive_consumer_pid, exclusive_consumer_tag, messages_ready, messages_unacknowledged, messages, messages_ready_ram, messages_unacknowledged_ram, messages_ram, messages_persistent, message_bytes, message_bytes_ready, message_bytes_unacknowledged, message_bytes_ram, message_bytes_persistent, head_message_timestamp, disk_reads, disk_writes, consumers, consumer_utilisation, memory, slave_pids, synchronised_slave_pids, state]. [root@centOSFrist ~]# rabbitmqctl list_queues -p APP_A name durable pid memory Listing queues ... tony-QUEUE false <[email protected]> 14040 QUEUE_A false <[email protected]> 21816
列出交换器和绑定
[root@centOSFrist ~]# rabbitmqctl list_exchanges -p APP_A Listing exchanges ... amq.headers headers amq.fanout fanout amq.direct direct amq.match headers direct amq.topic topic amq.rabbitmq.trace topic MY_EXCHANGE direct tony-EXCHANGE direct 其他参数如下: <exchangeinfoitem> must be a member of the list [name, type, durable, auto_delete, internal, arguments, policy].
查看RabbitMQ的日志
RabbitMQ的日志默认位置在:
[root@centOSFrist ~]# ls -ll /var/log/rabbitmq/ 总用量 32 -rw-r--r--. 1 rabbitmq rabbitmq 13247 11月 2 11:37 [email protected] -rw-r--r--. 1 rabbitmq rabbitmq 0 11月 1 17:04 [email protected] -rw-r--r--. 1 root root 60 11月 1 17:58 shutdown_err -rw-r--r--. 1 root root 49 11月 1 17:58 shutdown_log -rw-r--r--. 1 root root 60 11月 1 17:58 startup_err -rw-r--r--. 1 root root 355 11月 1 17:58 startup_log
[email protected] -> 节点名称为rabbit 主机为 centOSFrist 的日志 主要看这个日志
[email protected] -> 节点名称为rabbit 主机为 centOSFrist 的系统应用程序支持库日志 大部分是关于 Erlang的日志
可以使用tail 命令查看实时日志情况:
[root@centOSFrist ~]# tail -f /var/log/rabbitmq/[email protected] =ERROR REPORT==== 2-Nov-2016::11:36:57 === Error on AMQP connection <0.626.0> (192.168.0.2:59664 -> 192.168.0.21:5673, user: 'guest', state: opening): access to vhost 'APP_A' refused for user 'guest' =INFO REPORT==== 2-Nov-2016::11:36:57 === closing AMQP connection <0.626.0> (192.168.0.2:59664 -> 192.168.0.21:5673) =INFO REPORT==== 2-Nov-2016::11:37:32 === accepting AMQP connection <0.632.0> (192.168.0.2:59680 -> 192.168.0.21:5673)
如果日志需要轮换 可以使用命令进行轮换日志
[root@centOSFrist ~]# rabbitmqctl rotate_logs 1 Rotating logs to files with suffix "1" ... [root@centOSFrist ~]# ls -ll /var/log/rabbitmq/ 总用量 32 -rw-r--r--. 1 rabbitmq rabbitmq 0 11月 2 11:58 [email protected] -rw-r--r--. 1 rabbitmq rabbitmq 13320 11月 2 11:58 [email protected] -rw-r--r--. 1 rabbitmq rabbitmq 0 11月 2 11:58 [email protected] -rw-r--r--. 1 rabbitmq rabbitmq 0 11月 2 11:58 [email protected] -rw-r--r--. 1 root root 60 11月 1 17:58 shutdown_err -rw-r--r--. 1 root root 49 11月 1 17:58 shutdown_log -rw-r--r--. 1 root root 60 11月 1 17:58 startup_err -rw-r--r--. 1 root root 355 11月 1 17:58 startup_log
最后贴下我参考的官网链接:
权限 : http://www.rabbitmq.com/access-control.html
配置 : http://www.rabbitmq.com/configure.html
rabbitmqctrl : http://www.rabbitmq.com/man/rabbitmqctl.1.man.html
RabbitMQ 的详细介绍:请点这里
RabbitMQ 的下载地址:请点这里