RabbitMQ服务开发指南.docx
《RabbitMQ服务开发指南.docx》由会员分享,可在线阅读,更多相关《RabbitMQ服务开发指南.docx(46页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、招商银行信息技术标准编号占位符PaaS平台Rabb i tMQ服务开发指南招商姐行CHINA MfcKCHANIS BANK2016年1月8日发布2016年1月8日发布2016年1月8日实招商银行总行信息技术部招商银行总行信息技术部发布编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部2. 5. 4 headersheaders类型的Exchange不依赖于routing key与binding key的匹配规那么来路由消 息,而是根据发送的消息内容中的headers属性进行匹配。在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ
2、会取 到该消息的headers (也是一个键值对的形式),比照其中的键值对是否完全匹配Queue与 Exchange绑定时指定的键值对;如果完全匹配那么消息会路由到该Queue,否那么不会路由到该 Queue。2.6 Message acknowledgment (确认机制)、durability (持久化机制)在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出 现其他意外)的情况,这种情况下就可能会导致消息丧失。RabbitMQ提供了消息确认机制 来处理这种情况,消费者在消费完消息后发送一个回执给RabbitMQ, RabbitMQ收到消息回 执(Message
3、 acknowledgment)后才将该消息从Queue中移除;如果RabbitMQ没有收到回 执并检测到消费者的RabbitMQ连接断开,那么RabbitMQ会将该消息发送给其他消费者(如果 存在多个消费者)进行处理。这里不存在timeout概念,一个消费者处理消息时间再长也不 会导致该消息被发送给其他消费者,除非它的RabbitMQ连接断开。要注意的是在确认模式 开启时,如果消费端忘记发送回执给RabbitMQ,这将会导致严重的bug, Queue中堆积的消 息会越来越多;消费者重启后会重复消费这些消息。RabbitMQ还提供了消息持久化的机制。如果我们希望即使在RabbitMQ服务重启的
4、情况 下,也不会丧失消息,我们可以将Queue与Message都设置为可持久化的(durable),这样 可以保证绝大局部情况下我们的RabbitMQ消息不会丧失。但依然解决不了小概率丧失事件 的发生(比方RabbitMQ服务器已经接收到生产者的消息,但还没来得及持久化该消息时 RabbitMQ服务器就断电了),如果我们需要对这种小概率事件也要管理起来,需要采用事务 模式。2.7 Prefetch count前面我们讲到如果有多个消费者同时订阅同一个Queue中的消息,Queue中的消息会被第8页,共18页保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南平摊给多个消费者。这时如
5、果每个消息的处理时间不同,就有可能会导致某些消费者一直在 忙,而另外一些消费者很快就处理完手头工作并一直空闲的情况。可以通过设置 prefetchCount来限制Queue每次发送给每个消费者的消息数,比方我们设置 prefetchCount=l,那么Queue每次给每个消费者发送一条消息;消费者处理完这条消息后 Queue会再给该消费者发送一条消息。3消息确认机制3.1 确认机制在AMQP 0-9-1标准下,唯一能够保证消息不会丧失的方式是开启事务(transactions)模式将channel设置为transactional,发布消息,确认。但是事务(transactions)模式是重量级
6、的,而且会降低消息传递速率。为了对这一点进行改进, RabbitMQ 中引入了确认机制(confirmation mechanism)o客户端通过发送cofirm, select来开启确认机制,Broker端在接收到后会 返回confirm, select-ok,此时channel开启了确认模式。开启事务模式的channel不能开 启确认模式。一单channel进入确认模式,broker端和客户端会同时计算消息的序列数(在 第一个comfirm. select时从1开始计数)。Broker端通过向channel发送一个basic. ack 来确认消息已经发送到Brokero在basic, ac
7、k的delivery-tag中包含了消息的序列数。3.2 消息未确认的处理当broker端因为异常没能成功处理消息时,会向channel发送一个basic. nack 来说明消息没能成功处理。basic, nack 一般只在消息队列的erlang进程出现内部错误时才 会被发送。basic, nack中包含与basic, ack相同的字段信息。客户端接收到该信号后一般 会重新发送消息。开启确认机制的channel,对发送来的消息要么确认接受要么nack,但第9页,共18页编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部是消息确认的时间并不是实时的。3.3 消息确认时间说明消息在被
8、要路由到的所有队列接收后,broker端会发送basic. ack。对于需要 持久化的消息,broker会在消息完全持久化到磁盘后发送basic. ack。对于存在镜像队列的 情况,broker会在所有镜像队列都接收到消息后发送basic, ack。3.4 持久化消息的时延确认说明对于持久化的消息,RabbitMQ会在队列空闲时将消息写入磁盘,或者以批处理的 方式每隔几百毫秒写入磁盘一次,以减少对fsync函数的调用。所以在正常负载情况下,消 息确实认会有几百毫秒的时延。因此,为了提高处理效率,最好是在客户端对确认进行异步 处理。或者采用批处理发布消息,具体可以参加API设置。3.5 最大 D
9、eliveryTag确认的delivery tag是一个64bit的值,因此最大值为9223372036854775807c4内存告警机制RabbitMQ server 在启动时或者在调用 rabbitmqctl set_vm_memory_high_watermark 指令后开始探测RAM大小。一般来说,当内存使用超过40%时,RabbitMQ会启动内存告警并 且阻塞所有的连接。当内存告警清除(如将消息持久化到磁盘或者发送到了客户端)服务恢 复正常。默认的阈值为安装内存的40%。但这并不代表到达40%后RabbitMQ server的内存使 用不会继续上升,这时只有生产者会被阻塞。erlan
10、g的垃圾回收器最坏的情况下会使内存 的占用翻倍,因此最好启用swap分区或者虚拟内存来减小内存压力。4.1内存告警阈值配置内存告警阈值可以通过编辑配置文件进行调整。下面是一个将阈值设置为默认值 0.4的例子:rabbit, vm memory high watermark, 0.4.第10页,共18页编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部0. 4代表安装内存的40%或者只是进程可用虚拟地址空间的40%,如在32 位平台上,如果有4GB安装内存,那么40%是1.6GB,但是32位的Windows系统一般会将进 程的内存限制为2GB,此时阈值实际为2GB*40%,也就是8
11、20MB。除了通过百分比设置,阈 值还可以通过absolute参数设置绝对值。如通过如下配置可以将阈值设置为1024MBrabbit, vm_memory_high_watermark, absolute, 1073741824.或者rabbit, Lvm memory high watermark, absolute, 1024MiB.如果设定的阈值大于安装内存或者可用虚拟地址空间,阈值会自动被设置 为它们中更小的那个。当RabbitMQ Server启动时阈值会被写到日志中,如下。二INFO REPORT= 29-0ct-2015:15:43:27 =Memory limit set to
12、 2048MB.还可以通过rabbitmqctl来对运行中的broker告警阈值进行设置,通过 rabbitmqctl set_vm_memory_high_watermark 设置百分比或者 rabbitmqctl set_vm_mcmory_high_wa ter mark absolute memory-im it 设置绝对值。设置后会立即生效 直到RabbitMQ关闭。通过配置文件设置在broker重启后依然有效。在内存可热插拔的系统 中执行该命令,在参数不变的情况下阈值可能会改变,因为系统内存的总量可能已经改变。4.2 禁用生产者使用rabbitmqctl set_vm_memory
13、_high watermark 0指令可以立即出发内存告 警并且因此禁用所有的生产者发布消息(这在希望全局禁用消息发布时很有效)。4.3 受限地址空间如果在一个64位的系统中运行一个32位的Erlang VM,可访问内存是受限的。 server会检测并记录到日志中:二WARNING REPORT= 19-Dec-2013:11:27:13 =Only 2048MB of 12037MB memory usable due to limited address space.很可能会发生因为内存耗尽引起的崩溃。第11页,共18页保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南内存告
14、警系统不是完美的。一般来说停止消息发布会阻止内存占用上升,但是可能会 有其他程序继续提高内存占用。如果物理内存耗尽,OS会开始swap。但是如果在受限的地 址空间中运行,超过空间限制可能会导致VM崩溃,因此推荐的设置是Erlang的位数要与系 统的位数一致。4.4 磁盘写入阈值配置在broker到达告警阈值并且阻塞生产者之前,它会试图通过将队列中的消息写入磁盘 来释放内存。此时,持久化和非持久化的消息都会被写入到磁盘(持久化的消息已经存在 于磁盘上了,这里会将它们从内存中删除)。这个过程通常会在内存占用到达告警阈值的50%时开始(如默认告警值是0. 4时,写入 会在20%内存占用时开始)。磁盘
15、写入阈值可以通过修改 vm memory_h i gh watermark paging_rat io 来改变。如:rabbit, vm_memory_high_watermark_paging_ratio, 0. 75, vm memory high watermark, 0. 4 .这一配置会在内存占用为30% (40% *0. 75)时开始写入磁盘,在40%时阻塞消息发布。 如果将vm_memory_high_watermark_paging_ratio设置为大于1的值,队列不会将消息写入 磁盘。只会在内存告警时阻塞消息发布。平台无法识别时的应对方案:如果RabbitMQ server无
16、法识别当前系统,它会在日志中写入一条警告二WARNING REPORT= 29-Oct-2015: 17:23:44 =Unknown total memory size for your OS unix, magic_homebrew_os). Assuming memory size is 1024MB.这时,它会假定可用内存为1GB,默认vm memory_high watermark为0. 4,因此当 RabbitMQ占用的内存超过410MB时,告警会被触发。因此在RabbitMQ无法识别平台时,假 如内存为8GB,而想要将告警阈值设定为3GB可以通过 将vni_nieniory_hi
17、gh_watennark改为 3来完成。5磁盘告警机制当磁盘空间剩余低于一个特定的值时,RabbitMQ会阻塞生产者。这一机制出发点为:就 连非持久化的消息也可以在任何时候写入到磁盘,而磁盘空间耗尽会导致MQ Server崩溃。 RabbitMQ默认的告警值是50MB,当磁盘空间小于50MB时,RabbitMQ会阻塞消费者并且阻第12页,共18页保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南止非持久化的消息写入磁盘(持久化的消息还可以写入)。这一机制可以降低因为磁盘空间 耗尽而引起崩溃的可能性。但是这种可能性还是存在的,例如当消息写入磁盘速度非常快时, 磁盘空间很有可能会在两
18、次剩余空间探测之间耗尽。一个更保险的做法是将告警值设置跟系 统内存大小一致。当磁盘空间低于告警值时,全局流量控制会被触发。监控程序会以至少10s每次的频率 去探测Broker数据库所在磁盘分区上的剩余空间。监控程序在broker启动时同时启动,并 在broker日志中写入条目二INFO REPORT= 01-Jan-2016:14:52:41 =Disk free limit set to 953MB当无法识别平台时,监控程序会失效并且在日志中写入WARNING REP0RT= 01-Jan-2016: : 15:45:29 =Disabling disk free space monitor
19、ing在RabbitMQ集群中,磁盘告警是集群级别的,任何一个节点低于告警值都会触发所有 节点阻塞连接。RabbitMQ对磁盘剩余空间的探测策略为:探测频率取决于上次探测时磁盘 剩余空间的大小(以便在磁盘接近耗尽时及时告警)。通常探测频率为10s一次,但当接近 告警值时,探测频率会上升。当剩余空进逼近告警值时,频率会高达每秒10次。需要注意 的是这会增加系统的负载。5.1磁盘告警值(disk_free_limit)设置数据库所在的分区所需要的剩余空间默认是50MB,这个是通过disk_free_limit来设 置的。设置方式有两种:其一为通过修改配置文件,在文件中加入rabbit, disk_
20、freeimit, 1000000000 .或者rabbit, disk free limit, 1GB.另一种为通过rabbitmqctl set disk free limit xxMB指令来设置。这种方式可能会 在broker关闭后失效。因此要同时用两种方式以确保即使broker重启也能生效第13页,共18页保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南6高可用机制6.1高可用队列在RabbitMQ集群中,队列默认是仅存在于单节点(最初声明队列的那个节点)上的。 而路由(Exchanges)和绑定(Bindings)那么是存在于集群中所有节点上的。RabbitMQ提供
21、了队列在多个节点之间建立镜像的功能。每个镜像队列包括一个主队列(master)和一个或 者多个备用队列(slaves),当主队列丧失时,最老的备用队列会自动成为新的主队列。发布的队列中的消息会被复制到所有的备用队列。当消费者进行消费时,不管它是连 接到哪个节点,它都会从主队列中消费消息。当主队列中消息的消费被确认后,备用队列也 会将该消息删除掉。镜像队列提高了可用性。但是由于所有节点都存储相同的消息,并没有 提高集群的负载能力。由于镜像队列需要在节点间进行消息的同步,因此集群不能处理网络分区(network partition)的情况,因此在WAN环境下不适用。6.2镜像队列配置镜像队列通过策
22、略(policy)进行配置。策略的配置是非常灵活的,可以创立一个非 镜像队列,并随时将它变为镜像队列(反之亦然)。与镜像队列相比,非镜像队列不用进行 主备之间消息同步,因此运行会更快。在策略中设置镜像队列主要通过ha-mode和ha-params (可选)关键字。关键字含义 如下所示:ha-modeha-paramsResultal1(abse nt)队列在集群中所有节点之间做镜像。当新节点加入集群时,会在其上建立镜像ex actlycount队列只会在count个节点上做镜像。如果集群中节点数少于count,那么会在所有 大于count个,并且某个包含镜像节点的节点down掉,那么会在一个新
23、的节点上创立有 不要将ha-promote-on-shutdown设置为always,因为这可能导致镜像消息不同步nodesnode names 歹!J表队列只会在node names中所列的节点上做镜像。如果所列的节点不再当前集群中 中的节点在队列声明时处于on状态,那么当声明队列的客户端连接到该节点时,队列当高可用策略改变时,只要符合新策略,RabbitMQ会尽可能保证当前存在的镜像不改变。第14页,共18页保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南6.36.3“节点”策略和主节点迁移当策略改变而当前的主节点不存在于新的策略中时,主节点会发生改变。为了防止消 息丧失,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- RabbitMQ 服务 开发 指南
限制150内