RabbitMq architecture and cluster construction

In the participating platform development, the RabbitMq message queue is used for business decoupling, traffic peak shaving and delay queue timing tasks. On the basis of actual use, this article refers to relevant literature, summarizes the relevant architectural concepts of RabbitMq, and actually builds and deploys RabbitMq stand-alone, cluster, and mirror configurations, etc., re-learns and uses RabbitMq to deepen the understanding of RabbitMq, and at the same time It also provides reference for latecomers. There are inevitably omissions in the article. I hope readers can correct me. I am very grateful!

1. RabbitMq concept

RabbitMQ is an open source AMQP implementation. The server side is written in Erlang language and supports multiple clients, such as: Python, Ruby, .NET, Java, JMS, C, PHP, ActionScript, XMPP, STOMP, etc., and supports AJAX. It is used to store and forward messages in a distributed system, and performs well in terms of ease of use, scalability, and high availability.

AMQP, or Advanced Message Queuing Protocol, is an open standard for application layer protocols designed for message-oriented middleware. Message middleware is mainly used for decoupling between components, and the sender of the message does not need to know the existence of the message user, and vice versa.
The main features of AMQP are message-oriented, queue, routing (including point-to-point and publish/subscribe), reliability, and security.

2. RabbitMq architecture

insert image description here

2.1 Basic concepts

(1)Message
	消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,
	这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。
(2)Publisher
	消息的生产者,也是一个向交换器发布消息的客户端应用程序。
(3)Exchange
	交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
(4)Binding
	绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,
	所以可以将交换器理解成一个由绑定构成的路由表。
(5)Queue
	消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。
	一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
(6)Connection
	网络连接,比如一个TCP连接。
(7)Channel
	信道,多路复用连接中的一条独立的双向数据流通道。
	信道是建立在真实的TCP连接内地虚拟连接,AMQP命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。
	因为对于操作系统来说建立和销毁TCP都是非常昂贵的开销,所以引入了信道的概念,以复用一条TCP连接。
(8)Consumer
	消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。
(9)Virtual Host
	虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。
	每个 vhost 本质上就是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器、绑定和权限机制。
	vhost 是AMQ 概念的基础,必须在连接时指定,RabbitMQ 默认的vhost是 / 。
(10)Broker
	表示消息队列服务器实体。

2.2 ExchangeType

(1) Direct switch type (Direct)

Direct Exchange:直接交互式处理路由键。
需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配,这是一个完整的匹配。路由键就是BindingKey。

(2) Broadcast switch type (Fanout)

Fanout Exchange:广播式路由键。只需要简单的将队列绑定到交换机上。
一个发送到交换机的消息都被转发到与该交换机绑定的所有队列上。
很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。

(3) Topic exchange gold type (Topic)

Topic Exchange:主题式交换器。
通过消息的路由关键字和绑定关键字的模式匹配,将消息路由到被绑定的队列中。
这种路由器类型可以被用来支持经典的发布/订阅消息传输类型——使用主题名字空间作为消息寻址模式,将消息传递给那些部分或者全部匹配主题模式的多个消费者。
主题交换器类型的工作方式如下:绑定关键字用零个或多个标记构成,每一个标记之间用“.”字符分隔。绑定关键字必须用这种形式明确说明,并支持通配符:“*”匹配一个词组,“#”零个或多个词组。

2.3 cluster mode

The cluster nodes of RabbitMQ include memory nodes and disk nodes. Memory nodes store all data in memory, and disk nodes store data on disk. However, if the persistence of the message is turned on when the message is delivered, then even if it is a memory node, the data is still safely placed on the disk.
A rabbitmq cluster can share users, vhosts, queues, exchanges, etc. All data and status must be replicated on all nodes. An exception is those message queues that currently only belong to the node that created it, although they are visible and Readable by all nodes. Rabbitmq nodes can be dynamically added to the cluster. A node can be added to the cluster, or it can perform a basic load balancing from the cluster ring cluster. There are two kinds of nodes in the cluster:
memory nodes: save state to memory only (one exception: the persistent content of persistent queues will be saved to disk)
disk nodes: save state to memory and disk.
Memory nodes do not write to disk, but they perform better than disk nodes. In a cluster, only one disk node is needed to store the state.
If there are only memory nodes in the cluster, then they cannot be stopped, otherwise all state, messages, etc. will be lost.

RabbitMQ is developed with erlang, and the cluster is very convenient, because erlang is a distributed language by nature, but it does not support load balancing itself. Rabbit mode is roughly divided into the following three types: single mode, normal mode, and mirror mode:

1.单一模式:最简单的情况,非集群模式。

2.普通模式:默认的集群模式。
对于Queue来说,消息实体只存在于其中一个节点,A、B两个节点仅有相同的元数据,即队列结构。 
当消息进入A节点的Queue中后,consumer从B节点拉取时,RabbitMQ会临时在A、B间进行消息传输,把A中的消息实体取出并经过B发送给consumer。
所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连A或B,出口总在A,会产生瓶颈。 
该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体。 如果做了消息持久化,那么得等A节点恢复,然后才可被消费;如果没有持久化的话,然后就没有然后了……

3.镜像模式:把需要的队列做成镜像队列,存在于多个节点,属于RabbitMQ的HA方案。
该模式解决了上述问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在consumer取数据时临时拉取。 
该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。 所以在对可靠性要求较高的场合中适用。

3. RabbitMq deployment

3.1 Stand-alone installation

(1) Installation environment and version

linux服务器:	CentOS Linux release 7.2.1511 (Core)
rabbitmq版本:	rabbitmq-server-generic-unix-3.9.4.tar.xz
erlang版本:		otp_src_24.0.tar.gz
rabbitmq与erlang版本对应关系:https://www.rabbitmq.com/which-erlang.html

(2) Install erlang

(1)下载安装包
wget https://erlang.org/download/otp_src_24.0.tar.gz
(2)安装依赖
yum -y install gcc glibc-devel make ncurses-devel openssl-devel xmlto perl wget gtk2-devel binutils-devel
(3)解压、调整安装位置,以及安装路径
tar -zvxf otp_src_24.0.tar.gz 
mv otp_src_24.0 /usr/local/
cd /usr/local/otp_src_24.0/
mkdir ../erlang
(4)配置安装路径、安装
./configure --prefix=/usr/local/erlang
make install
(5)校验安装成功
查看一下是否安装成功
ll /usr/local/erlang/bin
 
添加环境变量,并刷新
echo 'export PATH=$PATH:/usr/local/erlang/bin' >> /etc/profile
source /etc/profile
 
甩一条命令,进入erl控制命令
erl

执行命令退出
halt(). 

(3) Install rabbitmq

(1)下载
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.4/rabbitmq-server-generic-unix-3.9.4.tar.xz

(2)安装解压工具xz解压安装包
yum install -y xz
xz -d rabbitmq-server-generic-unix-3.9.4.tar.xz
tar -vxf rabbitmq-server-generic-unix-3.9.4.tar

(3)移动安装文件位置,配置环境变量
mv rabbitmq_server-3.9.4/ /usr/local/rabbitmq
echo 'export PATH=$PATH:/usr/local/rabbitmq/sbin' >> /etc/profile
source /etc/profile

(4)启动命令
启动:
rabbitmq-server -detached

停止:
rabbitmqctl stop
 
状态:
rabbitmqctl status

开启web插件
rabbitmq-plugins enable rabbitmq_management

web访问
http://192.168.65.155:15672/

本机localhost访问默认账户密码 guest/guest

(5)用户管理配置权限
查看所有用户
rabbitmqctl list_users
 
添加一个用户
rabbitmqctl add_user test_user 123456
 
配置权限
rabbitmqctl set_permissions -p "/" test_user ".*" ".*" ".*"
 
查看用户权限
rabbitmqctl list_user_permissions test_user
 
设置tag
rabbitmqctl set_user_tags test_user administrator
 
删除用户(安全起见,删除默认用户)
rabbitmqctl delete_user guest

(6)重启后,即可使用账户密码test_user 123456访问
http://192.168.65.155:15672/

insert image description here

3.2 Cluster installation

这里选用三台主机,主机名分别是hidden1, hidden2, hidden3
1 在这三台机器中安装rabbitmq-server, 参考上面。

2 读取其中一个节点的cookie, 并复制到其他节点(节点之间通过cookie确定相互是否可通信)。
cookie存放在/var/lib/rabbitmq/.erlang.cookie或者$HOME/.erlang.cookie中。

3 逐个启动节点
rabbitmq-server -detached

4 查看各节点的状态: 
rabbitmqctl status
rabbitmqctl cluster_status

5 配置各节点的hosts文件( vim /etc/hosts)
192.168.65.155 rabbit_node1
192.168.65.156 rabbit_node2
192.168.65.157 rabbit_node3

6 建立集群
以rabbit_node1为主节点,在rabbit_node2上:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@rabbit_node1
rabbitmqctl start_app
rabbit_node3上的操作与rabbit_node2的雷同。
最后通过rabbitmqctl cluster_status查看集群的状态信息:

7 在访问web(http://192.168.65.155:15672)时, 
如果在Overview中的Nodes部分看到“Node statistics not available”的信息,说明在该节点上web管理插件还未启用。
直接运行rabbitmq-plugins enable rabbitmq_management即可。

注意事项:
(1)各个节点未启动之前拷贝.erlang.cookie文件;
(2)各节点之间防火墙端口号相互开放
默认端口说明
client端通信端口:5672
管理端口:15672
server间内部通信端口:25672
erlang发现端口:4369

insert image description here

3.3 Mirror cluster configuration

The RabbitMQ configured above is in the default cluster mode, but does not guarantee the high availability of the queue. Although the switches and bindings can be copied to any node in the cluster, the queue content will not be copied. Although this mode solves the pressure on the nodes of a project team, the downtime of the queue node directly causes the queue to be unusable and can only be restarted. Therefore, if the queue node is down or faulty and can be used normally, the content of the queue must be copied to the cluster For each node, a mirror queue needs to be created.

The mirror queue is based on the common cluster mode, so you still have to configure the normal cluster first, and then you can set up the mirror queue. We will continue with the above cluster.

I set up the mirror queue through the management side of the web page opened above, or through commands.
(1) Web page setting method:

1、点击admin菜单–>右侧的Policies选项–>左侧最下下边的Add/update a policy。
2、按照图中的内容根据自己的需求填写。
3、点击Add policy添加策略。

At this point, you will come to the amind menu of the web management side of your two rabbitmq servers and see the queue you just created. Next, let’s add a queue to see the effect. Here is just the test result, and the others will not be filled in.

(2) Set mirror queue policy by command

在任意一个节点上执行:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态保持一致。

查看策略:
rabbitmqctl list_policies

At this point the mirroring cluster is complete, you can create a queue on any node to see if the other two nodes will sync.
insert image description here
insert image description here

4. References

[1] https://www.cnblogs.com/guanghe/p/11023467.html
[2] https://www.jianshu.com/p/79ca08116d57
[3] https://www.cnblogs.com/fengyumeng/p/11133924.html
[4] https://blog.csdn.net/bbwangj/article/details/82954097

Guess you like

Origin blog.csdn.net/shy871/article/details/117598236
Recommended