赞
踩
RabbitMQ是由 LShift提供的一个 Advanced Message Queuing Protocol (AMQP)的开源实现,由以高性能、健壮以及可伸缩性出名的 Erlang写成(因此也是继承了这些优点)。
当前各种应用大量使用异步消息模型,并随之产生众多消息中间件产品及协议,标准的不一致使应用与中间件之间的耦合限制产品的选择,并增加维护成本。AMQP是一个提供统一消息服务的应用层标准协议,基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。当然这种降低耦合的机制是基于与上层产品,语言无关的协议。AMQP协议是一种二进制协议,提供客户端应用与消息中间件之间异步、安全、高效地交互。从整体来看,AMQP协议可划分为三层。
这种分层架构类似于OSI网络协议,可替换各层实现而不影响与其它层的交互。AMQP定义了合适的服务器端域模型,用于规范服务器的行为(AMQP服务器端可称为broker)。
Model层决定这些基本域模型所产生的行为,这种行为在AMQP中用”command”表示,在后文中会着重来分析这些域模型。
Session层定义客户端与broker之间的通信(通信双方都是一个peer,可互称做partner),为command的可靠传输提供保障。
Transport层专注于数据传送,并与Session保持交互,接受上层的数据,组装成二进制流,传送到receiver后再解析数据,交付给Session层。Session层需要Transport层完成网络异常情况的汇报,顺序传送command等工作。
AMQP当中有四个概念非常重要:虚拟主机(virtual host),交换机(exchange),队列(queue)和绑定(binding)。
虚拟主机(virtual host):一个虚拟主机持有一组交换机、队列和绑定。为什么需要多个虚拟主机呢?RabbitMQ当中,用户只能在虚拟主机的粒度进行权限控制。因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机。每一个RabbitMQ服务器都有一个默认的虚拟主机“/”。
队列(Queue):由消费者建立的,是messages的终点,可以理解成装消息的容器。消息一直存在队列里,直到有客户端或者称为Consumer消费者连接到这个队列并将message取走为止。队列可以有多个。
交换机(Exchange):可以理解成具有路由表的路由程序。每个消息都有一个路由键(routing key),就是一个简单的字符串。交换机中有一系列的绑定(binding),即路由规则(routes)。交换机可以有多个。多个队列可以和同一个交换机绑定,同时多个交换机也可以和同一个队列绑定。(多对多的关系)
三种交换机:
Fanout Exchange(不处理路由键):一个发送到交换机上的消息都会被转发到与该交换机绑定的所有队列上。Fanout交换机发消息是最快的。
Direct Exchange(处理路由键):如果一个队列绑定到该交换机上,并且当前要求路由键为X,只有路由键是X的消息才会被这个队列转发。
Topic Exchange(将路由键和某模式进行匹配,可以理解成模糊处理):路由键的词由“.”隔开,符号“#”表示匹配0个或多个词,符号“”表示匹配不多不少一个词。因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.”只会匹配到“audit.irs”
具体例子可以看下图
持久化:队列和交换机有一个创建时候指定的标志durable,直译叫做坚固的。durable的唯一含义就是具有这个标志的队列和交换机会在重启之后重新建立,它不表示说在队列当中的消息会在重启后恢复。那么如何才能做到不只是队列和交换机,还有消息都是持久的呢?
但是首先一个问题是,你真的需要消息是持久的吗?对于一个需要在重启之后回复的消息来说,它需要被写入到磁盘上,而即使是最简单的磁盘操作也是要消耗时间的。如果和消息的内容相比,你更看重的是消息处理的速度,那么不要使用持久化的消息。
当你将消息发布到交换机的时候,可以指定一个标志“Delivery Mode”(投递模式)。根据你使用的AMQP的库不同,指定这个标志的方法可能不太一样。简单的说,就是将 Delivery Mode设置成2,也就是持久的即可。一般的AMQP库都是将Delivery Mode设置成1,也就是非持久的。所以要持久化消息的步骤如下:
将交换机设成 durable。
将队列设成 durable。
将消息的 Delivery Mode 设置成2。
绑定(Bindings)如何持久化?我们无法在创建绑定的时候设置成durable。没问题,如果绑定了一个 durable的队列和一个durable的交换机,RabbitMQ会自动保留这个绑定。类似的,如果删除了某个队列或交换机(无论是不是 durable),依赖它的绑定都会自动删除。
注意两点:
RabbitMQ不允许绑定一个非坚固(non-durable)的交换机和一个durable的队列。反之亦然。要想成功必须队列和交换机都是durable的。
一旦创建了队列和交换机,就不能修改其标志了。例如,如果创建了一个non-durable的队列,然后想把它改变成durable的,唯一的办法就是删除这个队列然后重现创建。因此,最好仔细检查创建的标志。
sudo vim /etc/apt/sources.list
wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo apt-key add rabbitmq-signing-key-public.asc
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.2.2/rabbitmq-server_3.2.2-1_all.deb
sudo dpkg -i rabbitmq-server_3.2.2-1_all.deb
sudo apt-get install python-pip
sudo pip install pika
sudo rabbitmq-plugins enable rabbitmq_management
sudo rabbitmqctl stop
sudo rabbitmq-server –detached
wget http://hg.rabbitmq.com/rabbitmq-management/raw-file/rabbitmq_v3_2_1/bin/rabbitmqadmin
sudo cp rabbitmqadmin /usr/local/bin
cd /usr/local/bin
sudo chmod 777 rabbitmqadmin
#!/bin/sh
echo "deb http://www.rabbitmq.com/debian/ testing main" >>/etc/apt/sources.list
wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo apt-key add rabbitmq-signing-key-public.asc
sudo apt-get update
sudo apt-get install rabbitmq-server
sudo rabbitmq-plugins enable rabbitmq_management
sudo rabbitmqctl stop
sleep 5
sudo rabbitmq-server -detached
wget http://hg.rabbitmq.com/rabbitmq-management/raw-file/rabbitmq_v3_2_1/bin/rabbitmqadmin
sudo cp rabbitmqadmin /usr/local/bin
sudo chmod 777 /usr/local/bin/rabbitmqadmin
rabbitmq-plugins enable rabbitmq_management
invoke-rc.d rabbitmq-server stop
invoke-rc.d rabbitmq-server start
访问http://localhost:15672,用户名密码都是guest
复制完后重启下rabbitMQ。
复制好后别忘记还原.erlang.cookie的权限,否则可能会遇到错误:
设置好cookie后先将三个节点的rabbitMQ重启:
集群单连接的性能极限(镜像):
测试单连接发送1KB消息、32KB消息、64KB消息、128KB消息…的速度,直到无法发送消息或者性能有明显下降为止。每次测试要先purge清空队列。
集群多连接的性能极限(镜像):
用分别用32、64、128…个连接发送1KB、32KB、64KB…的消息,直到无法发送消息或者性能有明显下降为止。每次测试要先purge清空队列。
发送速度|CPU使用率|内存占用
1KB
32KB
64KB
128KB
单连接(每个连接100000个消息)
313|5%-6%|1.2%
234|6%|3%
186|7%-8%| 3.6%
133|6%-8%|19%
32个连接(每个连接10000个消息)
9900|110%-144%| 2.3%
7300-7500|190%-210%| 32%
5800|190%-230%|被强行停掉了因为内存超过阈值了(60%)
4200|260%-270%|强行被停掉了因为内存超过了阈值(60%)
64个连接(每个连接10000个消息)
20000|308%-320%|3.8%
15000|338%-348%|被强行停掉了因为内存超过了阈值(60%)
9000|348%-355%|被强行停掉了因为内存超过了阈值(60%)
5000-6000|355%370%| 被强行停掉了因为内存超过了阈值(60%)
128个连接(每个连接10000个消息)
26000-35000|255%-255%| 被强行停掉了因为内存超过了阈值(60%)
5000-13000|107%-255% | 被强行停掉了因为内存超过了阈值(60%)
900-7500|30%-314% | 被强行停掉了因为内存超过了阈值(60%)
0-4000|60%-355% | 被强行停掉了因为内存超过了阈值(60%)
集群单连接(镜像)(每个连接100000个消息)
313|13%-17%| 1.1%
233|16%-19%|10.8%
187|17%-20% |20.4%
133|19%-22%| 35.7%
集群32个连接(镜像)(每个连接10000个消息)
10000|270%-304%|2.2%
很不稳定、被强行停掉了
很不稳定、被强行停掉了
很不稳定、被强行停掉了
集群64个连接(镜像)(每个连接10000个消息)
很不稳定、被强行停掉了
很不稳定、被强行停掉了
很不稳定、被强行停掉了
很不稳定、被强行停掉了
集群128个连接(镜像)(每个连接10000个消息)
很不稳定、被强行停掉了
很不稳定、被强行停掉了
很不稳定、被强行停掉了
很不稳定、被强行停掉了
在单节点的测试中,可以发现64个连接的时候,服务器传输速度还很稳定,但是到了128连接就发现发送32KB大小的消息,传输速度浮动都很大,所以预测rabbitmq单节点的性能极限应该在128连接发送16KB大小的消息。后经过测试单节点极限在128连接发送8KB大小的消息。
在集群测试中,发现在32个连接发送1W个32KB大小的消息的时候,直接被强行停掉了,之后又测试了16KB,8KB,4KB的情况,发现只有4KB的情况下,才能稳定运行。由此大致得出集群(镜像队列)的极限性能是32个连接每个连接发1W个4KB大小的消息。速度5000/s左右,CPU占用350%-377%
与cinder联调
1. 同时启动rabbit1和rabbit2,cinder工作正常。
2. rabbit1stop,cinder工作正常。
3. 把rabbit1恢复,rabbit2stop,cinder工作正常。
与ceilometer联调
1. 同时启动rabbit1和rabbit2,ceilometor工作正常。
2. rabbit1stop,ceilometer工作正常。
3. 把rabbit1恢复,rabbit4stop,ceilometer工作正常。
与nova联调
4. 同时启动rabbit1和rabbit2,nova工作正常。
5. rabbit1stop,nova工作正常。
6. 把rabbit1恢复,rabbit4stop,nova工作正常。
监控rabbitMQ的方案
一些基本情况
每个模块的负责人会单独监控自己的模块,rabbitMQ的监控更倾向于发生问题之后的解决,比如purge掉队列中的冗余消息。另外,openstack中与rabbitmq相关的各个模块用的是同一个rabbitmq的user,这也就是说,不需要单独对某个模块add user,并且每个模块使用rabbitmq所建立的queue和exchange等都是自动完成的,也不需要care创建队列的权限等。基于以上一些情况,个人制定了下面的监控方案。
命令行查看最基本的运行状态
输入sudo rabbitmqctl -n rabbit@rabbit1 status查看该节点目前的状态
如果提示没有连接到该节点,则表示该节点挂掉了,需要重新启动。
如果能查看到该节点的状态,则输入sudo rabbitmqctl –n rabbit@rabbit1 list_connections查看连接是否都是running状态, 如果有block状态则表示该进程目前阻塞了。
在目前节点状态查看中,可以查看已经内存使用率、磁盘剩余空间等状态。
所要监控的信息
内存占用:超过60%报警。
磁盘占用:超过70%报警。
sudo rabbitmqctl status
每个队列的name、messages、memory。
队列的消息数上限为10*10^4个,memory最大为512MB。如果超过这些阈值,就需要立即进行处理,以免影响整个服务正常运转。
sudo rabbitmqctl list_queues name messages memory
每个连接的state、timeout。
在我们的整个服务中,每个连接的state都应该是running,最大延迟为1s。如果状态不是running或者延迟过高,则需要立即处理。
sudo rabbitmqctl list_connections host state timeout
如果相关阈值需要修改,与每个模块相关负责人商议之后可修改阈值。
在192.168.8.14和192.168.8.35上,有两个脚本,可以查看rabbitmq消息队列状态。
sudo sh /usr/local/bin/monitor_rabbitmq_queue_state.sh
根据提示来进行一些输入就可以了。
截图如下:
Web插件
查看connection exchange queue等状态,消息数量,内存占用,disc占用等。需要根据实际情况判断是否正常。
消息状态:
节点状态:
connection:
channel:
exchange:
queue:
policy:
一般来说rabbitMQ自带各种流量阈值限制,如果挂掉一般都是因为超过了阈值,要等实际运行的时候进行阈值调整。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。