rabbitmq是一种消息队列服务,可以实现rpc,一般情况下openstack的rpc用的就是用它做的,它有很多的用途。除了Qpid以外它是唯一实现了AMQP标准的代理服务器
1.安装
安装rabbitmq是一件十分容易的事情,在yum源正常的情况下直接即可
yum install rabbitmq-server -y
2.信道
当你连接rmq后,你的应用程序与rmq服务器之间就会创建一条TCP连接,当你通过认证打开TCP连接后就会创建一条AMQP信道,这条信道是创建在真实TCP连接内的虚拟连接,当很多人对此rmq服务器进行连接使用时,这条TCP连接内就会有很多条信道。
主要原因是因为对于操作系统来说创建销毁一条TCP连接是很昂贵的!并且使用TCP连接的话很快就会达到因为根据需求所设置的调度线程数,很快就会遇到瓶颈!(在一条TCP连接内创建多少信道是没有限制的)
3.basic.consume与basic.get(知道即可)
basic.consume会让消费者一直从队列中获取消息,比如消费者消费(拒绝)最近消费的消息后就可以自动从队列中拿下一条
basic.get则是仅仅只获取单条消息,下一条不会再拿了,需要不断的再次执行basic.get,明显这种方式对性能有影响
正常情况下消费者理应使用basic.consume来提升吞吐量
4.交换器
headers允许你匹配消息的头部而不是你设置的路由规则,剩下的与direct完全一致,但是性能上会差很多,这种不实用,现在几乎已经没有在用了
direct很简单是一种完全根据路规则进行匹配投递的交换器
fanout是一种完全发布的交换器,当有一条消息进来后它会直接将其发布到绑定到fanout交换器的所有队列内
topic是一种模糊匹配的交换器,可以理解成对direct交换器匹配了正则后进行发布
5.vhost
rmq服务器都可以创建虚拟消息服务器,它是一个mini的rmq服务器,内部拥有着自己的队列交换机以及绑定,这样多租户之间就没有影响了
rabbitmqctl list_vhosts # 列出所有vhosts
rabbitmqctl add_vhost v1 # 创建一个v1的vhosts
rabbitmqctl delete_vhost v1 # 删除v1
6.基本操作
systemctl start rabbitmq-server # 开启rmq服务
systemctl stop rabbitmq-server # 关闭rmq服务
rabbitmqctl start_app # 开启内部vhost
rabbitmqctl stop_app # 关闭内部vhost,服务不会关闭
rabbitmqctl add_user bfmq miao # 创建一个bfmq用户,密码是miao
rabbitmqctl delete_user bfmq # 删除bfmq用户
rabbitmqctl list_users # 列出所有用户
rabbitmqctl change_password bmfq meng # 把bfmq用户的密码改成meng
rabbitmqctl list_queues -p v1 # 列出v1内所有队列
rabbitmqctl list_queues -p v1 name messages consumers memory # 列出v1内所有队列的名字,内部消息数目,消费者数目,内存使用
rabbitmqctl list_exchanges -p v1 列出v1内所有交换器,出来你自己创建的交换器以外,会有amq.topic、amq.fanout、amq.match、amq.headers、amq.direct这几个默认自动生命的交换器以及在列出所有条目的底部有一个direct类型没有名字的交换器(匿名交换器,所有的队列默认都会把绑定到此交换器)
rabbitmqctl list_queues -p v1 name type durable auto_delete # 列出v1内所有交换器的名字,类型,是否可持久化,是否自动删除
7.权限关系
用户对vhost的控制
读:有关消费消息的任何操作(可清空队列)
写:发布消息
配置:队列及交换机的创建删除
rabbitmqctl set_permissions -p v1 bfmq ".*" ".*" ".*" # 以前设置过再次执行即为修改成新设置的权限
-p v1:这条权限设置是给与哪个vhost,如果不填写则是默认/,即对/ vhost进行了权限设置
bfmq:被授予权限的用户
".*" ".*" ".*":授予的权限。顺序是配置,写,读
".*"代表所有权限
“”代表无此权限
“*a*”代表内部名字含有a的所有队列及交换机
rabbitmqctl set_permissions -p v2 bfmq "" "*a*" ".*" 给与bfmq在v2内对所有队列及交换机读权限,名字内包含a的队列及交换机写权限,对内部所有队列及交换机都无配置权限
rabbitmqctl list_permissions -p v1 # 查看对v1 vhost里所有权限,如果不填写则是对/ vhost进行查看
rabbitmqctl clear_permissions -p v1 bfmq # 清空bfmq在v1上的权限设置
rabbitmqctl list_user_permissions bfmq # 查看bfmq用户的所有权限
8.集群
通过更改port在同一台机器上搭建集群(当然正经来说肯定是不同的物理机了),默认端口5672,我们用5672,5673,5674来模拟
RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbitmq_1 /sbin/rabbitmq-server -detached # -detached是让在后台运行
RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=rabbitmq_2 /sbin/rabbitmq-server -detached
RABBITMQ_NODE_PORT=5674 RABBITMQ_NODENAME=rabbitmq_3 /sbin/rabbitmq-server -detached
rabbitmq_1作为第一个节点无需操作,但是rabbitmq_2与rabbitmq_3在加入集群前需要清空他们上面的元数据,首先需要停止erlang程序
rabbitmqctl -n [email protected] stop_app # [email protected],bfmq是我的主机名
rabbitmqctl -n [email protected] stop_app
rabbitmqctl -n [email protected] reset
rabbitmqctl -n [email protected] reset
组建集群
rabbitmqctl -n [email protected] join_cluster [email protected] # 把[email protected]加入到[email protected]集群内
rabbitmqctl cluster_status -n [email protected] # 查看[email protected]集群信息
rabbitmqctl cluster_status -n [email protected]出现下列信息
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected]]}]},
{running_nodes,[[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]}]}]
我们看到running_nodes只有[email protected]一个,刚才加入的[email protected]没有运行,因为我们刚才stop_app了,现在启动它再查看信息
rabbitmqctl -n [email protected] start_app && rabbitmqctl cluster_status -n [email protected]
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected]]}]},
{running_nodes,[[email protected],[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]},{[email protected],[]}]}]
好了现在[email protected]也在running_nodes里了,我们再将[email protected]也加进来并且启动然后查看信息
rabbitmqctl -n [email protected] join_cluster [email protected] --ram && rabbitmqctl -n [email protected] start_app && rabbitmqctl cluster_status -n [email protected] # --ram是让此节点以内存节点加入,rmq集群内至少需要2个磁盘节点
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected]]},{ram,[[email protected]]}]},
{running_nodes,[[email protected],[email protected],[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]},{[email protected],[]},{[email protected],[]}]}]
我们看到[email protected],[email protected]是disc而[email protected]是ram正是我们所设置的
离开集群
rabbitmqctl -n [email protected] stop_app
rabbitmqctl -n [email protected] reset # reset会直接清空节点的状态,因此原本在集群内的状态也会被清掉
rabbitmqctl -n [email protected] start_app # 此时[email protected]就已经是一个独立节点了
rabbitmqctl cluster_status -n [email protected]
Cluster status of node [email protected] ...
[{nodes,[{disc,[[email protected],[email protected]]}]},
{running_nodes,[[email protected],[email protected]]},
{cluster_name,<<"[email protected]">>},
{partitions,[]},
{alarms,[{[email protected],[]},{[email protected],[]}]}]
不同机器上搭建集群,那就不需要调整端口号了,我以1.1.1.1、10.10.10.10、100.100.100.100为例子直接写一遍流程
3台机子上操作systemctl start rabbitmq-server
将1.1.1.1内的/var/lib/rabbitmq/.erlang.cookie复制覆盖到10.10.10.10、100.100.100.100的/var/lib/rabbitmq/.erlang.cookie
10.10.10.10、100.100.100.100操作
systemctl restart rabbitmq-server
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster [email protected] && rabbitmqctl start_app
如果写好了hosts文件就可以把ip用主机名替换掉,其实就是把@后主机名变更下以及把erlang.cookie统一
9.升级
独立节点升级很容易,只需要解压新版包后直接运行即可。
集群则不可以!这样做会清除掉集群的相关配置及数据,你需要使用RabbitMQ Management插件备份当前配置,然后关闭所有生产者并且等待消费者消费完所有消息后关闭节点,解压新版本包到现有的安装目录,选用其中一个磁盘节点作为升级节点,当它运行时,该节点会把持久化的集群数据升级到新版本,然后启动其他磁盘节点,他们会获取数据自动升级,最后再打开内存节点,升级完毕。