RabbitMQ简介
以熟悉的电商场景为例,如果商品服务和订单服务是两个不同的微服务,在下单的过程中订单服务需要调用商品服务进行扣库存操作。按照传统的方式,下单过程要等到调用完毕之后才能返回下单成功,如果网络产生波动等原因使得商品服务扣库存延迟或者失败,会带来较差的用户体验,如果在高并发的场景下,这样的处理显然是不合适的,那怎么进行优化呢?这就需要消息队列登场了。
消息队列提供一个异步通信机制,消息的发送者不必一直等待到消息被成功处理才返回,而是立即返回。消息中间件负责处理网络通信,如果网络连接不可用,消息被暂存于队列当中,当网络畅通的时候在将消息转发给相应的应用程序或者服务,当然前提是这些服务订阅了该队列。如果在商品服务和订单服务之间使用消息中间件,既可以提高并发量,又降低服务之间的耦合度。
RabbitMQ就是这样一款我们苦苦追寻的消息队列。RabbitMQ是一个开源的消息代理的队列服务器,用来通过普通协议在完全不同的应用之间共享数据。
RabbitMQ是使用Erlang语言来编写的,并且RabbitMQ是基于AMQP协议的。Erlang语言在数据交互方面性能优秀,有着和原生Socket一样的延迟,这也是RabbitMQ高性能的原因所在。可谓“人如其名”,RabbitMQ像兔子一样迅速。
RabbitMQ集群模式
普通模式
默认模式,以两个节点(rabbit01、rabbit02)为例来进行说明。对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构。当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈。当rabbit01节点故障后,rabbit02节点无法取到rabbit01节点中还未消费的消息实体。如果做了消息持久化,那么得等rabbit01节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。
镜像模式
把需要的队列做成镜像队列,存在与多个节点属于RabbitMQ的HA方案。该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用。
ubuntu下安装RabbitMQ集群
1.配置节点hosts
先配置节点hosts,用于集群,再安装RabbitMQ, 不然安装后可能读不到配置的hosts。如果有自建DNS更佳。
1
2
3
4
|
vim /etc/hosts #在每个节点上编辑/etc/hosts文件写入以下内容
192.168.10.101 node1
192.168.10.102 node2
192.168.10.103 node3
|
2.rabbitmq-server安装
以ubuntu为例,使用下面快速安装脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/bin/sh
## 官方最新版安装脚本
## Install RabbitMQ signing key
curl -fsSL https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc | sudo apt-key add -
## Install apt HTTPS transport
sudo apt-get install apt-transport-https
## Add Bintray repositories that provision latest RabbitMQ and Erlang 21.x releases
sudo tee /etc/apt/sources.list.d/bintray.rabbitmq.list <<EOF
deb https://dl.bintray.com/rabbitmq-erlang/debian bionic erlang-21.x
deb https://dl.bintray.com/rabbitmq/debian bionic main
EOF
## Update package indices
sudo apt-get update -y
## Install rabbitmq-server and its dependencies
sudo apt-get install rabbitmq-server -y --fix-missing
|
3.在每个节点启用管理插件
1
2
3
4
5
|
sudo rabbitmq-plugins enable rabbitmq_management
sudo rabbitmq-plugins enable rabbitmq_tracing
#如果服务已经在启动则先执行 rabbitmqctl stop_app
#然后再执行rabbitmq-plugins enable
#最后重新start:rabbitmqctl start_app
|
4.加入集群
因为RabbitMQ集群是基于erlang同步的,所以先配置使各个节点 中 .erlang.cookie文件一致。
1
2
3
4
5
6
7
8
9
|
#启动集群前先统一所有节点.erlang.cookie文件,注意文件权限
scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq/
#systemctl start rabbitmq-server.service 启动所有节点
#假定node1是主节点, 其他节点依次执行
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@node1 #node1的名称与 rabbitmqctl cluster_status 中的信息一致
#rabbitmqctl join_cluster rabbit@node1 --ram #添加为内存节点,默认为磁盘
rabbitmqctl start_app
|
集群重启顺序(如果没有内存节点请忽略)
集群重启的顺序是固定的,并且是相反的。 如下所述:
- 启动顺序:磁盘节点 => 内存节点
- 关闭顺序:内存节点 => 磁盘节点
5.创建RabbitMQ用户
设置用户命令, 建议创建好集群后再设置, 不然会被集群配置覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
rabbitmqctl add_user sunday sunday # 创建账号
rabbitmqctl set_user_tags sunday administrator # 设置用户角色
rabbitmqctl set_permissions -p "/" sunday ".*" ".*" ".*" # 设置用户权限
rabbitmqctl list_users # 查看用户列表
rabbitmqctl change_password username password # 修改用户密码
#其他命令
rabbitmqctl status #查看服务信息
rabbitmqctl cluster_status #查看集群状态
Cluster status of node rabbit@node1 ...
[{nodes,[{disc,[rabbit@node1,rabbit@node2,rabbit@node3]}]},
{running_nodes,[rabbit@node3,rabbit@node2,rabbit@node1]},
{cluster_name,<<"rabbit@node1">>},
{partitions,[]},
{alarms,[{rabbit@node3,[]},{rabbit@node2,[]},{rabbit@node1,[]}]}]
|
6.命令行开启镜像策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#开启所有队列为镜像队列"^"匹配名称为所有, "^ha."匹配名称为ha开头的
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
-p Vhost: 可选参数,针对指定vhost下的queue进行设置
Name: policy的名称
Pattern: queue的匹配模式(正则表达式)
Definition:镜像定义,包括三个部分ha-mode, ha-params, ha-sync-mode
ha-mode:指明镜像队列的模式,有效值为 all/exactly/nodes
all:表示在集群中所有的节点上进行镜像
exactly:表示在指定个数的节点上进行镜像,节点的个数由ha-params指定
nodes:表示在指定的节点上进行镜像,节点名称通过ha-params指定
ha-params:ha-mode模式需要用到的参数
ha-sync-mode:进行队列中消息的同步方式,有效值为automatic和manual
priority:可选参数,policy的优先级
|
docker-compose快速安装单节点
这里使用的启用mqtt的镜像,无需mqtt也可以使用别的
集群安装请参考 docker-compose安装rabbitmq集群(主从集群—》镜像集群)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
version: "3"
services:
rabbitmq-mqtt:
container_name: rabbitmq-mqtt
environment:
- RABBITMQ_MQTT_DEFAULT_PASS=admin
- RABBITMQ_MQTT_DEFAULT_USER=admin
- RABBITMQ_MQTT_VHOST=/
- RABBITMQ_DEFAULT_PASS=admin
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_VHOST=/
image: cyrilix/rabbitmq-mqtt:latest
volumes:
- ./data:/var/lib/rabbitmq
ports:
- 25672:25672/tcp
- 4369:4369/tcp
- 5671:5671/tcp
- 5672:5672/tcp
- 8883:8883/tcp
- 15672:15672/tcp
- 1883:1883/tcp
restart: always
|