由于rabbitmq是基于 erlang语言开发,全部要先安装erlangnode
这里我下载的是19.2的版本,地址为https://www.erlang.org/downloads/19.2linux
下载编译安装包:c++
cd /mnt wget http://erlang.org/download/otp_src_19.2.tar.gz
解缩web
tar -zxvf otp_src_19.2.tar.gz
安装编译依赖正则表达式
yum -y install gcc gcc-c++ autoconf automake zlib zlib-devel openssl openssl-devel pcre-devel ncurses-devel
编译安装浏览器
cd /mnt/otp_src_19.3 && ./configure --prefix=/opt/er1ang && make && make install
设置环境变量安全
修改 /etc/profile在最后添加以下代码 ERLANG_HOME=/opt/erlang export PATH=$PATH:$ERLANG_HOME/bin export ERLANG_HOME source /etc/profile
进入官网选择下载的版本服务器
http://www.rabbitmq.com/releases/rabbitmq-server/
我选择的是3.6.10版本cookie
cd /opt
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/rabbitmq-server-generic-unix-3.6.10.tar.xz
xz -d rabbitmq-server-generic-unix-3.6.10.tar.xz
tar -xvf rabbitmq-server-generic-unix-3.6.10.tar
mv rabbitmq-server-generic-unix-3.6.10 rabbitmq
设置环境变量app
编辑/etc/profile文件,在最后添加以下代码 export PATH=$PATH:/opt/rabbitmq/sbin export RABBITMQ_HOME=/opt/rabbitmq source /etc/profile
运行rabbitmq
rabbitmq-server -detached
查看启动状态 rabbitmqctl status
[root@node-2 opt]# rabbitmqctl status
Status of node 'rabbit@node-2'
[{pid,27273},
{running_applications,
[{rabbit,"RabbitMQ","3.6.10"},
{mnesia,"MNESIA CXC 138 12","4.14.3"},
{ranch,"Socket acceptor pool for TCP protocols.","1.3.0"},
{ssl,"Erlang/OTP SSL application","8.1.1"},
{public_key,"Public key infrastructure","1.4"},
{crypto,"CRYPTO","3.7.3"},
{os_mon,"CPO CXC 138 46","2.4.2"},
{rabbit_common,
"Modules shared by rabbitmq-server and rabbitmq-erlang-client",
"3.6.10"},
{xmerl,"XML parser","1.3.13"},
{compiler,"ERTS CXC 138 10","7.0.4"},
{asn1,"The Erlang ASN1 compiler version 4.0.4","4.0.4"},
{syntax_tools,"Syntax tools","2.1.1"},
{sasl,"SASL CXC 138 11","3.0.3"},
{stdlib,"ERTS CXC 138 10","3.3"},
{kernel,"ERTS CXC 138 10","5.2"}]},
{os,{unix,linux}},
{erlang_version,
"Erlang/OTP 19 [erts-8.3] [source] [64-bit] [smp:2:2] [async-threads:64] [hipe] [kernel-poll:true]\n"},
{memory,
[{total,49620264},
{connection_readers,0},
{connection_writers,0},
{connection_channels,0},
{connection_other,0},
{queue_procs,2832},
{queue_slave_procs,0},
{plugins,0},
{other_proc,17182792},
{mnesia,61040},
{metrics,184080},
{mgmt_db,0},
{msg_index,43528},
{other_ets,2088952},
{binary,49848},
{code,21385570},
{atom,891849},
{other_system,7911021}]},
{alarms,[]},
{listeners,[{clustering,25672,"::"},{amqp,5672,"::"}]},
{vm_memory_high_watermark,0.4},
{vm_memory_limit,779028070},
{disk_free_limit,50000000},
{disk_free,45861027840},
{file_descriptors,
[{total_limit,924},{total_used,2},{sockets_limit,829},{sockets_used,0}]},
{processes,[{limit,1048576},{used,152}]},
{run_queue,0},
{uptime,5047},
{kernel,{net_ticktime,60}}]
每个RabbitMQ 服务器都能建立虚拟的消息服务器,咱们称之为虚拟主机 (virtual host) , 简称为 vhost 。每个 vhost 本质上是一个独立的小型 RabbitMQ 服务器,拥有本身独立的队列、 交换器及绑定关系等,井且它拥有本身独立的权限。 vhost 就像是虚拟机与物理服务器同样,它 们在各个实例间提供逻辑上的分离,为不一样程序安全保密地运行数据,它既能将同 一个 RabbitMQ 中的众多客户区分开,又能够避免队列和交换器等命名冲突。 vhost 之间是绝对隔离 的,没法将 vhostl 中的交换器与 vhost2 中的队列进行绑定,这样既保证了安全性,又能够确保 可移植性。若是在使用 RabbitMQ 达到必定规模的时候,建议用户对业务功能、场景进行归类 区分,并为之分配独立的 vhost。
vhost是AMQP 概念的基础,客户端在链接的时候必须制定一个 vhost. RabbitMQ 默认创 建的 vhost为 “/”, 若是不须要多个 vhost 或者对 vhost 的概念不是很理解,那么用这个默认的 vhost 也是很是合理的,使用默认的用户名 guest 和密码 guest 就能够访问它。可是为了安全和 方便,建议从新创建 个新的用户来访问它。
可使用 rabbitmqctl add vhost {vhost} 命令建立一个新的 vhost ,大括号里的参 数表示 vhost 的名称。
[root@node-2 opt]# rabbitmqctl add_vhost vhost Creating vhost "vhost"
查看vhosts列表
[root@node-2 opt]# rabbitmqctl list_vhosts Listing vhosts / vhost
对应的删除 vhost 的命令是: rabbitmqctl delete_vhost {vhost) ,其中大括号里 面的参数表示 vhost 的名称。删除一个 vhost 同时也会删除其下全部的队列、交换器、绑定关系、 用户权限、参数和策略等信息。
[root@node-2 opt]# rabbitmqctl delete_vhost vhost Deleting vhost "vhost" [root@node-2 opt]# [root@node-2 opt]# rabbitmqctl list_vhosts Listing vhosts /
AMQP 协议中并无指定权限在 host 级别仍是在服务器级别实现,由具体的应用自定义。 在RabbitMQ 中,权限控制则是以 host 为单位的 。当建立一个用户时,用户一般会被指派给至少一个 vhost ,而且只能访问被指派的 vhost 内的队列、交换器和绑定关系等。所以, RabbitMQ 中的授予权限是指在 vhost 级别对用户而言的权限授予。
相关的授予权限命令为: rabbitmqctl set permissions [-p vhost] {user) {conf) {write) {read) 。其 中各个参数的含义以下所述。 ~ vhost 授予用户访问权限的 host 名称,能够设置为默认值,即vhosts为 “/”
user:能够访问指定 vhost 的用户名。
conf: 一个用于匹配用户在哪些资源上拥有可配置权限的正则表达式。
write:一个用于匹配用户在哪些资源上拥有可写权限的正则表达式。
read:一个用于匹配用户在哪些资源上拥有可读权限的正则表达式
授予root用户能够访问虚拟主机vhost,而且在全部资源上都具有可配置、可读、可写的权限,代码以下:
[root@node-1 ~]# rabbitmqctl set_permissions -p vhost root ".*" ".*" ".*" Setting permissions for user "root" in vhost "vhost"
授予root用户可访问虚拟主机vhost2,在以“queue”开头的资源上具有可配置权限,而且在全部资源上拥有可写、可读权限
[root@node-1 ~]# rabbitmqctl set_permissions -p vhost2 root "^queue.*" ".*" ".*" Setting permissions for user "root" in vhost "vhost2"
在 RabbitMQ 中有两个 Shell 命令能够列举权限信息。第一个命令是 rabbitmqctl list_permissions [-p vhost) ,用来显示虚拟主机上的权限;第二个命令是 rabbitmqctl list_user permissions {username) ,用来显示用户的权限。
,
清除也是在vhost级别对用户而言的,清除权限的命令为clear_permissions [-p <vhost>] <username> 其中vhost用于设置禁止用户访问的虚拟主机名称,默认为“/”, username为禁止访问虚拟主机的用户名
[root@node-1 ~]# rabbitmqctl clear_permissions -p vhost root Clearing permissions for user "root" in vhost "vhost"
在RabbitMQ 中,用 户是访问控制 (Access Control)的基本单元,且单个用户能够跨越 vhost 进行受权。针对一至多个 vhost ,用户能够被赋予不一样级别的访问权限,并使用标准的 用户名和密码来认证用户。
建立用户的命令为 rabbitmqctl add user {username} {password} ,username表示建立的用户,password表示为建立用户的登陆密码
建立一个用户为root,密码为root的用户
rabbitmqct1 add_user root root
能够经过 rabbitmqctl change_password {username} {newpassword} 命令来更 改指定用户的密码 其中 username 表示要变动密码的用户名称, newpassword 表示要变动的新的密码。
一样能够清除密码,这样用户就不能使用密码登陆了,对应的操做命令为 rabbitmqctl clear_password {username} ,其中 username 表示要清除密码的用户名称。
使用 rabbitmqctl authentiçate_user {userηame} {password} 能够经过密码来验证用户,其中 username 表示须要被验证的用户名称, password 表示密码
下面示例中分别采用root123和root321来验证root用户
[root@node-1 ~]# rabbitmqctl authenticate_user root root321 Authenticating user "root" Error: failed to authenticate user "root" [root@node-1 ~]# [root@node-1 ~]# rabbitmqctl authenticate_user root root123 Authenticating user "root" Success
删除用户命令为 rabbitmqctl delete_user <username>
删除root用户
[root@node-1 ~]# rabbitmqctl delete_user root Deleting user "root"
罗列全部用户
[root@node-1 ~]# rabbitmqctl list_users Listing users guest [administrator]
用户的角色分为 5种类型。
none:无任何角色。新建立的用户的角色默认为none
management:能够访问 Web 管理页面。
policymaker:包含 management 的全部权限。
monitoring:包含 management 的全部权限,而且能够看到全部链接、信道及节点相关的信息。
administartor:包含 monitoring 的全部权限,井且能够管理用户、 机、 权限、策略、参数等。 administator 表明了最高的权限。
用户的角色能够经过rabbitmqctl set_user_tags <username> <tag> 设置,其中 username 参数表示须要设置角色的用户名称;tag 参数用于设置 0个、1 个或者多个的角色,设置以后任何以前现有的身份都会被删除。
[root@node-1 ~]# rabbitmqctl list_users Listing users guest [administrator] root [] [root@node-1 ~]# rabbitmqctl set_user_tags root monitoring Setting tags for user "root" to [monitoring] [root@node-1 ~]# rabbitmqctl list_users -q guest [administrator] root [monitoring] [root@node-1 ~]# rabbitmqctl set_user_tags root policymaker,management Setting tags for user "root" to ['policymaker,management'] [root@node-1 ~]# [root@node-1 ~]# rabbitmqctl list_users -q guest [administrator] root [policymaker,management]
前面讲述的都是使用 rabbitmqctl 工具来管理 RabbitMQ,有些时候是否会以为这种方式是否是不太友好?并且为了可以运行 rabbitmqctl 工具,当前的用户须要拥有访问 Erlang cookie 的权限,因为服务器多是 guest 或者 root 用户身份来运行的,所以你须要得到这些文件的访问权限 ,这样就引伸出来 些权限管理的问题。
RabbitMQ开发团队也考虑到了这种状况,而且开发了 RabbitMQ management 插件 RabbitMQ management 插件一样是由 Erlang 语言编写 的,而且和 RabbitMQ 服务运行在同一个 Erlang 虚拟机中。
为root用户设置全部权限
RabbitMQ management 插件能够提供 Web 管理界面用来管理如前面所述的虚拟主机、用 户等,也能够用来管理队列、交换器 、绑定关系、策略、 参数等 ,还能够用来监控 RabbitMQ 服务的状态及一些数据统计类信息,可谓是功能强大,基本上可以涵盖全部 RabbitMQ 管理的 功能。
在使用 Web 管理界面以前须要先启用 RabbitMQ management 插件, RabbitMQ 提供了不少 的插件,默认存放在 $RABBITMQ_HOME /plugins 目录下,以下所示
上面以.ez结尾的都是rabbitmq的插件,其中rabbitmq_management-3.6.10.ez就是rabbitmq management插件,启动插件的命令是rabbitmq-plugins,其语法格式为
rabbitmq-plugins [-n <node>] <command> [<command options>] 启动插件是使用rabbitmq-plugins enable [plugin-name] 关闭插件的命令是 rabbitmq-plugins disable [plugin-name]
执行rabbitmq-plugins enable rabbitmq_management来启动rabbitmq management插件
[root@node-1 plugins]# rabbitmq-plugins enable rabbitmq_management The following plugins have been enabled: amqp_client cowlib cowboy rabbitmq_web_dispatch rabbitmq_management_agent rabbitmq_management Applying plugin configuration to rabbit@node-1... started 6 plugins.
能够经过 rabbitmq-plugins list 命令来查看当前插件的使用状况 以下所示。其中 标记为 [E*]的为显式启动,而 [e*] 为隐式启动, 如显式启动 rabbitmq_management 插件 ,会同时隐式启动 amqp_client 、cowboy、 cowlib rabbitmq_management_age、rabbitmq_web_dispatch 等另外 5个插件。
[root@node-1 plugins]# rabbitmq-plugins list Configured: E = explicitly enabled; e = implicitly enabled | Status: * = running on rabbit@node-1 |/ [e*] amqp_client 3.6.10 [e*] cowboy 1.0.4 [e*] cowlib 1.0.2 [ ] rabbitmq_amqp1_0 3.6.10 [ ] rabbitmq_auth_backend_ldap 3.6.10 [ ] rabbitmq_auth_mechanism_ssl 3.6.10 [ ] rabbitmq_consistent_hash_exchange 3.6.10 [ ] rabbitmq_event_exchange 3.6.10 [ ] rabbitmq_federation 3.6.10 [ ] rabbitmq_federation_management 3.6.10 [ ] rabbitmq_jms_topic_exchange 3.6.10 [E*] rabbitmq_management 3.6.10 [e*] rabbitmq_management_agent 3.6.10 [ ] rabbitmq_management_visualiser 3.6.10 [ ] rabbitmq_mqtt 3.6.10 [ ] rabbitmq_recent_history_exchange 3.6.10 [ ] rabbitmq_sharding 3.6.10 [ ] rabbitmq_shovel 3.6.10 [ ] rabbitmq_shovel_management 3.6.10 [ ] rabbitmq_stomp 3.6.10 [ ] rabbitmq_top 3.6.10 [ ] rabbitmq_tracing 3.6.10 [ ] rabbitmq_trust_store 3.6.10 [e*] rabbitmq_web_dispatch 3.6.10 [ ] rabbitmq_web_mqtt 3.6.10 [ ] rabbitmq_web_mqtt_examples 3.6.10 [ ] rabbitmq_web_stomp 3.6.10 [ ] rabbitmq_web_stomp_examples 3.6.10 [ ] sockjs 0.3.4 [root@node-1 plugins]#
默认guest用户只能在本机上访问进入管理页面,其余用户需设置
[root@node-1 plugins]# rabbitmqctl set_user_tags root administrator Setting tags for user "root" to [administrator] [root@node-1 plugins]# [root@node-1 plugins]# rabbitmqctl list_users Listing users guest [administrator] root [administrator] [root@node-1 plugins]#
浏览器中输入http://192.168.10.129:15672
输入root的用户名和密码成功登陆
这里演示为三台服务器搭建的一个集群环境,每台服务器上都安装rabbitmq
vi /etc/hosts
192.168.10.129 node-1
192.168.10.130 node-2
192.168.10.131 node-3
以节点 node-1的.erlang.cookie为目标,修改node2和node3上的.erlang.cookie
注意:如不能保存,先chmod 600 .erlang.cookie 修改后在改回400权限chmod 400 .erlang.cookie
[root@node-1 sbin]# rabbitmq-server -detached [root@node-2 sbin]# rabbitmq-server -detached [root@node-3 sbin]# rabbitmq-server -detached
接下来为了将每一个节点组成一个集群,须要以 node-l 节点为基准,将 node-2 、node-3 节点 加入 node-l 节点的集群中。这3 个节点是平等的,若是想调换彼此的加入顺序也何尝不可。首 先将 node2 节点加入 nodel 节点的集群中,须要执行以下4 个命令步骤。
[root@node-2 sbin]# rabbitmqctl stop_app Stopping rabbit application on node 'rabbit@node-2' [root@node-2 sbin]# [root@node-2 sbin]# rabbitmqctl reset Resetting node 'rabbit@node-2' [root@node-2 sbin]# rabbitmqctl join_cluster rabbit@node-1 Clustering node 'rabbit@node-2' with 'rabbit@node-1' [root@node-2 sbin]# [root@node-2 sbin]# rabbitmqctl start_app Starting node 'rabbit@node-2' [root@node-2 sbin]# [root@node-2 sbin]# rabbitmqctl cluster_status Cluster status of node 'rabbit@node-2' [{nodes,[{disc,['rabbit@node-1','rabbit@node-2']}]}, {running_nodes,['rabbit@node-1','rabbit@node-2']}, {cluster_name,<<"rabbit@node-1">>}, {partitions,[]}, {alarms,[{'rabbit@node-1',[]},{'rabbit@node-2',[]}]}] [root@node-2 sbin]# [root@node-2 sbin]#
最后将 node-3 节点也加入 node-l 节点所在的集群中,这3 个节点组成了一个完整的集群。 在任意一个节点中均可以看到以下的集群状态。
[root@node-3 ~]# rabbitmqctl stop_app Stopping rabbit application on node 'rabbit@node-3' [root@node-3 ~]# [root@node-3 ~]# rabbitmqctl reset Resetting node 'rabbit@node-3' [root@node-3 ~]# rabbitmqctl join_cluster rabbit@node-1 Clustering node 'rabbit@node-3' with 'rabbit@node-1' [root@node-3 ~]# rabbitmqctl start_app Starting node 'rabbit@node-3' [root@node-3 ~]# rabbitmqctl cluster_status Cluster status of node 'rabbit@node-3' [{nodes,[{disc,['rabbit@node-1','rabbit@node-2','rabbit@node-3']}]}, {running_nodes,['rabbit@node-1','rabbit@node-2','rabbit@node-3']}, {cluster_name,<<"rabbit@node-1">>}, {partitions,[]}, {alarms,[{'rabbit@node-1',[]},{'rabbit@node-2',[]},{'rabbit@node-3',[]}]}] [root@node-3 ~]# [root@node-3 ~]#
若是在node-2上用命令rabbitmqctl stop_app关闭一个节点,在node-1和node-3上查看集群节点信息
node-2上关闭
[root@node-2 sbin]# rabbitmqctl stop_app Stopping rabbit application on node 'rabbit@node-2' [root@node-2 sbin]#
node-1上查看集群状况
[root@node-1 ~]# rabbitmqctl cluster_status Cluster status of node 'rabbit@node-1' [{nodes,[{disc,['rabbit@node-1','rabbit@node-2','rabbit@node-3']}]}, {running_nodes,['rabbit@node-3','rabbit@node-1']}, {cluster_name,<<"rabbit@node-1">>}, {partitions,[]}, {alarms,[{'rabbit@node-3',[]},{'rabbit@node-1',[]}]}]
node-3上查看集群状况
[root@node-3 ~]# rabbitmqctl cluster_status Cluster status of node 'rabbit@node-1' [{nodes,[{disc,['rabbit@node-1','rabbit@node-2','rabbit@node-3']}]}, {running_nodes,['rabbit@node-3','rabbit@node-1']}, {cluster_name,<<"rabbit@node-1">>}, {partitions,[]}, {alarms,[{'rabbit@node-3',[]},{'rabbit@node-1',[]}]}]
若是关闭了集群中的全部节点,必须保证最后关闭的节点第一个启动,如,我按照前后顺序关闭了node-一、node-二、node-3 也就是node-3是最后一个关闭的。那么在启动是先启动node-3节点,node-1和node-2谁先启动均可以
不然机会启动失败(10次30秒的等待时间)
若是最后一个关闭的节点最终因为某些异常而没法启动,则能够经过 rabbitrnqctl forget_cluster_node 命令来将此节点剔出当前集群。若是集 群中的全部节点因为某些非正常因素,好比断电而关闭,那么集群中的节点都会认为还有其余 节点在它后面关闭,
此时须要调用 rabbitrnqctl force_boot 命令来启动一个节点,以后 集群才能正常启动。
在使用 rabbitrnqctl cluster_status 命令来查看集群状态时会有 {nodes [{disc , [rabbit@node-l , rabbit@node-2 , rabbit@node-3] 这一项信息,其中的 disc 标注了 RabbitMQ 节点的类型。 RabbitMQ 中的每个节点,不论是单一节点系统或者是集群中的一部分 要么是内存节点,要么是磁盘节点。 内存节点将全部的队列、 交换器、绑定关系、用户、权限和 host 的元数据定义都存储在内存中,而磁盘节点则将这些信息存储到磁盘中。单节点的集群中必然只有 磁盘类型的节点,不然当重启 RabbitMQ以后,全部关于系统的配置信息都会丢失。不过在集群中, 能够选择配置部分节点为内存节点,这样能够得到更高的性能。
好比将 node-2 节点加入 nod 节点的时候能够指定 node-2节点的类型为内存节点。
[root@node-2 /] rabbitmqctl join_cluster rabbit@node-l --ram
这样在以 node-l和 node-2 组成的集群中就会有一个磁盘节点和一个内存节点,默认不添加 "-ram"参数则表示此节点为磁盘节点。
若是集群已经搭建好了,那么也可使用 rabbitmqctl change_cluster_node_type {disc ,ram} 命令来切换节点的类型,其中 disc 表示磁盘节点,而 ram 表示内存节点。举例, 这里将上面 node-2 节点由磁盘节点转变为内存节点。
[root@node-2 /]# rabbitmqctl stop_app
Stopping rabbit application on node 'rabbit@node-2' [root@node-2 /]# rabbitmqctl change_cluster_node_type ram Turning 'rabbit@node-2' into a ram node [root@node-2 /]# [root@node-2 /]# rabbitmqctl start_app Starting node 'rabbit@node-2' [root@node-2 /]# rabbitmqctl cluster_status Cluster status of node 'rabbit@node-2' [{nodes,[{disc,['rabbit@node-3','rabbit@node-1']},{ram,['rabbit@node-2']}]}, {running_nodes,['rabbit@node-1','rabbit@node-3','rabbit@node-2']}, {cluster_name,<<"rabbit@node-1">>}, {partitions,[]}, {alarms,[{'rabbit@node-1',[]},{'rabbit@node-3',[]},{'rabbit@node-2',[]}]}]
有两种方式将一个节点从集群中剔除,好比将node-2从集群中踢出。
在node-2上关闭服务rabbitmqctl stop_app,在node-1或者node-3上执行
[root@node-3 ~]# rabbitmqctl forget_cluster_node rabbit@node-2 Removing node 'rabbit@node-2' from cluster [root@node-3 ~]# [root@node-3 ~]# rabbitmqctl cluster_status Cluster status of node 'rabbit@node-3' [{nodes,[{disc,['rabbit@node-1','rabbit@node-3']}]}, {running_nodes,['rabbit@node-1','rabbit@node-3']}, {cluster_name,<<"rabbit@node-1">>}, {partitions,[]}, {alarms,[{'rabbit@node-1',[]},{'rabbit@node-3',[]}]}]
直接在node-2节点上执行
[root@node-2 /]# rabbitmqctl stop_app Stopping rabbit application on node 'rabbit@node-2' [root@node-2 /]# rabbitmqctl reset Resetting node 'rabbit@node-2' [root@node-2 /]# [root@node-2 /]# rabbitmqctl start_app Starting node 'rabbit@node-2' [root@node-2 /]# [root@node-2 /]# rabbitmqctl cluster_status Cluster status of node 'rabbit@node-2' [{nodes,[{disc,['rabbit@node-2']}]}, {running_nodes,['rabbit@node-2']}, {cluster_name,<<"rabbit@node-2">>}, {partitions,[]}, {alarms,[{'rabbit@node-2',[]}]}] [root@node-2 /]#