RabbitMQ服务开发指南.docx
招商银行信息技术标准编号占位符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会取 到该消息的headers (也是一个键值对的形式),比照其中的键值对是否完全匹配Queue与 Exchange绑定时指定的键值对;如果完全匹配那么消息会路由到该Queue,否那么不会路由到该 Queue。2.6 Message acknowledgment (确认机制)、durability (持久化机制)在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出 现其他意外)的情况,这种情况下就可能会导致消息丧失。RabbitMQ提供了消息确认机制 来处理这种情况,消费者在消费完消息后发送一个回执给RabbitMQ, RabbitMQ收到消息回 执(Message acknowledgment)后才将该消息从Queue中移除;如果RabbitMQ没有收到回 执并检测到消费者的RabbitMQ连接断开,那么RabbitMQ会将该消息发送给其他消费者(如果 存在多个消费者)进行处理。这里不存在timeout概念,一个消费者处理消息时间再长也不 会导致该消息被发送给其他消费者,除非它的RabbitMQ连接断开。要注意的是在确认模式 开启时,如果消费端忘记发送回执给RabbitMQ,这将会导致严重的bug, Queue中堆积的消 息会越来越多;消费者重启后会重复消费这些消息。RabbitMQ还提供了消息持久化的机制。如果我们希望即使在RabbitMQ服务重启的情况 下,也不会丧失消息,我们可以将Queue与Message都设置为可持久化的(durable),这样 可以保证绝大局部情况下我们的RabbitMQ消息不会丧失。但依然解决不了小概率丧失事件 的发生(比方RabbitMQ服务器已经接收到生产者的消息,但还没来得及持久化该消息时 RabbitMQ服务器就断电了),如果我们需要对这种小概率事件也要管理起来,需要采用事务 模式。2.7 Prefetch count前面我们讲到如果有多个消费者同时订阅同一个Queue中的消息,Queue中的消息会被第8页,共18页保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南平摊给多个消费者。这时如果每个消息的处理时间不同,就有可能会导致某些消费者一直在 忙,而另外一些消费者很快就处理完手头工作并一直空闲的情况。可以通过设置 prefetchCount来限制Queue每次发送给每个消费者的消息数,比方我们设置 prefetchCount=l,那么Queue每次给每个消费者发送一条消息;消费者处理完这条消息后 Queue会再给该消费者发送一条消息。3消息确认机制3.1 确认机制在AMQP 0-9-1标准下,唯一能够保证消息不会丧失的方式是开启事务(transactions)模式将channel设置为transactional,发布消息,确认。但是事务(transactions)模式是重量级的,而且会降低消息传递速率。为了对这一点进行改进, RabbitMQ 中引入了确认机制(confirmation mechanism)o客户端通过发送cofirm, select来开启确认机制,Broker端在接收到后会 返回confirm, select-ok,此时channel开启了确认模式。开启事务模式的channel不能开 启确认模式。一单channel进入确认模式,broker端和客户端会同时计算消息的序列数(在 第一个comfirm. select时从1开始计数)。Broker端通过向channel发送一个basic. ack 来确认消息已经发送到Brokero在basic, ack的delivery-tag中包含了消息的序列数。3.2 消息未确认的处理当broker端因为异常没能成功处理消息时,会向channel发送一个basic. nack 来说明消息没能成功处理。basic, nack 一般只在消息队列的erlang进程出现内部错误时才 会被发送。basic, nack中包含与basic, ack相同的字段信息。客户端接收到该信号后一般 会重新发送消息。开启确认机制的channel,对发送来的消息要么确认接受要么nack,但第9页,共18页编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部是消息确认的时间并不是实时的。3.3 消息确认时间说明消息在被要路由到的所有队列接收后,broker端会发送basic. ack。对于需要 持久化的消息,broker会在消息完全持久化到磁盘后发送basic. ack。对于存在镜像队列的 情况,broker会在所有镜像队列都接收到消息后发送basic, ack。3.4 持久化消息的时延确认说明对于持久化的消息,RabbitMQ会在队列空闲时将消息写入磁盘,或者以批处理的 方式每隔几百毫秒写入磁盘一次,以减少对fsync函数的调用。所以在正常负载情况下,消 息确实认会有几百毫秒的时延。因此,为了提高处理效率,最好是在客户端对确认进行异步 处理。或者采用批处理发布消息,具体可以参加API设置。3.5 最大 DeliveryTag确认的delivery tag是一个64bit的值,因此最大值为9223372036854775807c4内存告警机制RabbitMQ server 在启动时或者在调用 rabbitmqctl set_vm_memory_high_watermark 指令后开始探测RAM大小。一般来说,当内存使用超过40%时,RabbitMQ会启动内存告警并 且阻塞所有的连接。当内存告警清除(如将消息持久化到磁盘或者发送到了客户端)服务恢 复正常。默认的阈值为安装内存的40%。但这并不代表到达40%后RabbitMQ server的内存使 用不会继续上升,这时只有生产者会被阻塞。erlang的垃圾回收器最坏的情况下会使内存 的占用翻倍,因此最好启用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%,也就是820MB。除了通过百分比设置,阈 值还可以通过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 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_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服务开发指南内存告警系统不是完美的。一般来说停止消息发布会阻止内存占用上升,但是可能会 有其他程序继续提高内存占用。如果物理内存耗尽,OS会开始swap。但是如果在受限的地 址空间中运行,超过空间限制可能会导致VM崩溃,因此推荐的设置是Erlang的位数要与系 统的位数一致。4.4 磁盘写入阈值配置在broker到达告警阈值并且阻塞生产者之前,它会试图通过将队列中的消息写入磁盘 来释放内存。此时,持久化和非持久化的消息都会被写入到磁盘(持久化的消息已经存在 于磁盘上了,这里会将它们从内存中删除)。这个过程通常会在内存占用到达告警阈值的50%时开始(如默认告警值是0. 4时,写入 会在20%内存占用时开始)。磁盘写入阈值可以通过修改 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无法识别当前系统,它会在日志中写入一条警告二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_high_watennark改为 3来完成。5磁盘告警机制当磁盘空间剩余低于一个特定的值时,RabbitMQ会阻塞生产者。这一机制出发点为:就 连非持久化的消息也可以在任何时候写入到磁盘,而磁盘空间耗尽会导致MQ Server崩溃。 RabbitMQ默认的告警值是50MB,当磁盘空间小于50MB时,RabbitMQ会阻塞消费者并且阻第12页,共18页保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南止非持久化的消息写入磁盘(持久化的消息还可以写入)。这一机制可以降低因为磁盘空间 耗尽而引起崩溃的可能性。但是这种可能性还是存在的,例如当消息写入磁盘速度非常快时, 磁盘空间很有可能会在两次剩余空间探测之间耗尽。一个更保险的做法是将告警值设置跟系 统内存大小一致。当磁盘空间低于告警值时,全局流量控制会被触发。监控程序会以至少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 monitoring在RabbitMQ集群中,磁盘告警是集群级别的,任何一个节点低于告警值都会触发所有 节点阻塞连接。RabbitMQ对磁盘剩余空间的探测策略为:探测频率取决于上次探测时磁盘 剩余空间的大小(以便在磁盘接近耗尽时及时告警)。通常探测频率为10s一次,但当接近 告警值时,探测频率会上升。当剩余空进逼近告警值时,频率会高达每秒10次。需要注意 的是这会增加系统的负载。5.1磁盘告警值(disk_free_limit)设置数据库所在的分区所需要的剩余空间默认是50MB,这个是通过disk_free_limit来设 置的。设置方式有两种:其一为通过修改配置文件,在文件中加入rabbit, disk_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提供 了队列在多个节点之间建立镜像的功能。每个镜像队列包括一个主队列(master)和一个或 者多个备用队列(slaves),当主队列丧失时,最老的备用队列会自动成为新的主队列。发布的队列中的消息会被复制到所有的备用队列。当消费者进行消费时,不管它是连 接到哪个节点,它都会从主队列中消费消息。当主队列中消息的消费被确认后,备用队列也 会将该消息删除掉。镜像队列提高了可用性。但是由于所有节点都存储相同的消息,并没有 提高集群的负载能力。由于镜像队列需要在节点间进行消息的同步,因此集群不能处理网络分区(network partition)的情况,因此在WAN环境下不适用。6.2镜像队列配置镜像队列通过策略(policy)进行配置。策略的配置是非常灵活的,可以创立一个非 镜像队列,并随时将它变为镜像队列(反之亦然)。与镜像队列相比,非镜像队列不用进行 主备之间消息同步,因此运行会更快。在策略中设置镜像队列主要通过ha-mode和ha-params (可选)关键字。关键字含义 如下所示:ha-modeha-paramsResultal1(abse nt)队列在集群中所有节点之间做镜像。当新节点加入集群时,会在其上建立镜像ex actlycount队列只会在count个节点上做镜像。如果集群中节点数少于count,那么会在所有 大于count个,并且某个包含镜像节点的节点down掉,那么会在一个新的节点上创立有 不要将ha-promote-on-shutdown设置为always,因为这可能导致镜像消息不同步nodesnode names 歹!J表队列只会在node names中所列的节点上做镜像。如果所列的节点不再当前集群中 中的节点在队列声明时处于on状态,那么当声明队列的客户端连接到该节点时,队列当高可用策略改变时,只要符合新策略,RabbitMQ会尽可能保证当前存在的镜像不改变。第14页,共18页保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南6.36.3“节点”策略和主节点迁移当策略改变而当前的主节点不存在于新的策略中时,主节点会发生改变。为了防止消 息丧失,RabbitMQ会保持当前的主节点知道至少有一个备用节点完成同步(可能会比拟耗 时)。同步完成后,节点会失效,消费者将会被断开连接因此需要重连。例如原来为A,B 的队列因为策略的改变变为C,D,首先会变为A,C,D。当队列同步完成后才会变为C,D, 而A会关闭。6.4 专用队列专用队列顾名思义是指某个连接专有的队列,在连接关闭后专用队列会被删除。因此, 给专用队列设置镜像或者进行持久化是没用的,因为假如该队列所在的节点down掉时连接 肯定会关闭,此时队列会被删除。因此,专用队列永远不会被设置镜像或者持久化。6.5 集群高可用策略设置范例例子1, all例子:设置名称以" ha “开头的队列在集群中所有节点上设置镜像rabbitmqctlrabbitmqctl set policy ha-all ha. ' "ha-mode”:all'rabbitmqctl (Windows)rabbitmqctl set_policy ha-all "ha ha-mode: all APIPUT /api/policies/%2f/ha-all “pattern”:ha., “definition": /zha-mode :allWeb UI1 .进入 Admin > Policies > Add / update a policy; 2. Name 输入 “ha-all”,Patti 输入”人ha, “,” ha-mode输入 “all” ; 3.点击 Add policyo例子2, exactly例子:设置名称以” two “开头的队列在集群中两个节点上做镜 像,并且开启自动同步。rabbitmq ctlrabbitmqctl set_policy ha-two two 'ha-mode:exactly”, ha-params”:2, ha-sync-mode:“automatic'rabbitmq ctl (Windows)rabbitmqctl set_policy ha-two two, fJ , 11 cl14t ha-mode : exactly , ha-params :2, hasyncmode : automatic j APIPUT /api/policies/%2f/ha-two“pattern:Fvo ,“definition:“ha-mode:exactly”,第15页,共18页编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部/zha-paramsz,:2, ha-sync-mode": "automatic”1 ,进入 Admin > Policies > Add / update a policy; 2. Name 输入 “ha-two",PatternWeb UI 入”八two. “,” ha-mode输入 “exactly” 设置ha-params”= 2,并将 type 设置为"Number ha-sync-niode ="automatic“ ; 3.点击 Add policy。例子3, node例子:设置名称以“ nodes "开头的队列在集群中特定节点上做镜 像。rabbitmqc tlrabbitmqctl set_policy ha-nodes "nodes'. 'z,ha-mode/,: “nodes”, ha-paranis: nodeA,nodeB'rabbitmqc tl (Windows)rabbitmqctl set_policy ha-nodes “nodes'.” fij i ij a1 n11 I ha-mode : nodes , ha-params :L nodeA , nodeB J APIPUT /api/policies/%2f/ha-nodes pattern : nodes. , definition : ha-mode : nodes , ha-params :L nodeA , “nodeB"Web UI1 .进入 Admin > Policies > Add / update a policy; 2. Name 输入“ha-nodes”,Patte 轴入 nodes. , ha mode轴入nodes并将type设置为List ,在随后的子表中轴 “nodeA” 和 “nodeB” ; 3.点击 Add policy。新加入节点的同步一个节点可能会在任何时候加入集群。如果集群中的队列被配置为全集群镜像,队列 会在新加入的节点上做一个备用队列。此时,新节点上的队列是空的,不会包含任何队列中 己存在的消息。备用队列会接收新发布的消息,因而在一段时间之后备用队列中的消息与镜 像队列中队尾的消息时一致的。如果此时不断对镜像队列中的消息进行消费,队头消息中新 备用队列不包含的局部会越来越少,直到最后备用队列与镜像队列完全同步完成。这是要注 意的是,只有当消息被不断消费时这一同步才可能会发生。按照上一段的描述不难发现,新加入的备用队列不能给它加入前队列中已经存在的消息 提供可用保障。除非通过显示的同步调用对其进行同步。当显式同步进行时,队列停止相应 请求直至同步完成,因此如果队列中的消息正在被消费,推荐让备用队列自然完成同步。而 只对处于空闲状态的队列进行显式同步。6.6 显式同步显式同步的触发方式有两种:自动和手动。如果队列被设置为自动同步,那么每当有新 的备用队列创立,RabbitMQ就会对该队列进行同步,队列会停止相应请求直到同步完成。第16页,共18页编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部队列的同步方式可以通过在策略中配置ha-sync-mode进行选择:如果为automatic, 那么为自动同步;如果为manual,那么为手动同步。默认为手动同步。查看同步的备用队列的 命令如下:rabbitmqctl list_queues name slave_pids synchronised_slave_pids手动同步队列的命令如下:rabbitmqctl sync_qucue name取消同步命令如下:rabbitmqctl cancel sync queue name节点的启停和同步如果镜像队列的主队列所在的节点被关闭,那么其他节点上的备用队列会自动成为主队 列。持续这一操作,直至最后只剩一个节点,此时该节点上的队列是主队列并且没有被用队 列。如果队列是持久化的,它们如果这个最后的节点被关闭掉,重启后队列中已经被持久化 的消息仍然会存在。一般来说,这时如果你重启其他包括镜像队列的节点,它们会重新加入 到镜像队列之中。然而,重新加入的备用队列不知道它包含的消息是否与主队列中的消息一致。因此,当 一个备用队列重新加入到一个镜像队列中时一,它会丢弃掉本身持久化的消息作为一个空的队 列加入到镜像队列中,随后的行为会跟一个新加入集群的节点行为一致。6.7 主节点停止时未同步备节点的切换配置当关闭主节点时很有可能备节点并未跟主节点完全同步。在集群滚动升级时,这种情 况很有可能发生。通常,如果主节点的关闭是受控的(如显式的关闭RabbitMQ服务或者显 式的关掉OS), RabbitMQ不会切换到未同步的备节点上而是会关闭整个队列,这样可以防止 数据丧失。如果主节点的关闭时不受控的(如节点突然崩溃或者网络中断),此时及时备节 点是未同步的,RabbitMQ也会切换到备节点。如果希望在任何情况下,主节点停掉时都能够切换到备用节点,可以在策略设置时将 ha-promote-on-shutdown 设置为 “always” , ha-promote-on-shutdown 的默认值是 when-syncedo ha-promoteon-shutdown 设置为 always 还是 when-synced,是对可用优先还 是消息可靠性优先的抉择,需要根据具体场景设置。在PaaS上RabbitMQ设置为when-synced 优先保证消息的可靠性。第17页,共18页保密级别:内部保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南目录刖S11 简介2手册目的21.1 使用范围2名词定义22 RabbitMQ 介绍3ConnectionFactory> Connection> Channel32.1 Queue (消息队列)4Exchange (路由交换器)、routing key42.2 Binding> Binding key5Exchange Types52.3 fanout6direct62.3.1 topic7headers82.4 Message acknowledgment (确认机制)、durability (持久化机制) 8Prefetch count83 在云平台应用中使用PaaS RabbitMQ服务36依赖说明363.1 得到服务实例连接37使用RabbitMQ服务收发消息40编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部610主节点无法启动的处理当所有的备节点都处于关闭状态时,主节点也down掉了。此时如果主节点能够 重启,它仍然会成为主节点。但如果主节点无法重启,需要在目前停止的备节点中选择一个 新的主节点。但是根据上面集群节点重启小节我们知道,备节点重启后为了消息跟主节点同 步是会丢弃掉所有持久化数据并且跟主节点重新同步的。因此,在备节点启动前必须调用 rabbitmqctl forget_cluster_node命令,告诉备节点主节点将会被移出集群。此时,备节 点中最后停掉的那个会被选为新的主节点。6.11 镜像队列的相关原理如前文所述,每个镜像队列都包括分布在不同节点上的一个主队列和几个备队列。除了 消息发布以外的其他所有操作都仅仅会影响主队列,主队列会随后将操作执行的影响广播到 备队列中。备队列会以跟主队列同样的方式来执行操作,以维持队列状态的一致。因此,从 镜像队列中消费实际上仅仅是从主队列中消费。当备队列出现故障时,RabbitMQ除了产生几条故障记录几乎不用做任何操作:主队列 仍然是主队列,客户端也不会被通知或者采取任何措施。要注意集群内节点之间是相互判断 对方是否正常是隔一段时间才进行的,因此备队列故障可能不会立即就被检测到。而且 RabbitMQ的流量控制(flow control)机制也会导致消息发布延迟。备队列之一会被选为新的主队列。一般是启动时间最长的那个备队列会成为新的队列, 因为它跟主队列同步的可能性最高。然而如果所有的备队列都没有跟主队列同步,仅在主队 列中存在的消息会丧失。新的主队列会假设之前所有的消费者都已经断开连接,因而它会将所有已经发送到客户 端但却没确认的消息重新加入队列。这些消息里可能会包含已经被消费过的消息,因为有可 能确认信号是在发送到broker端时主队列出现故障或者在主队列已经确认信号在向备队列 广播时发生故障。客户端的消费会被取消(参加后文中消费取消的章节)。由于消息被重新加入队列,从队列中消费消息的客户端必须要知道它们随后消费的消息 中可能会包含已经消费过的消息。在备节点成为主节点的过程中,发布到镜像队列的消息不会丧失:因为发布到镜像队列 的消息不但会被发送到主队列而且也会被直接发送到所有的备队列。因此,当主队列出现故 障时,消息会被继续发送到备节点,并且在备队列成为主队列后消息会被加入到队列之中。同样,在确认模式开启时,即使主队列(或任何的备队列)在消息发布完成和确认消 息发送到生产者之间发生故障,消息仍然能够得到确认。因此,从生产者的角度看,向镜像第18页,共18页编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部队列中发布消息跟向任何其他类型的队列发布消息没有区别。而如果消费者是在未开启确认 模式(noAck二true)的情况下从队列中进行消费,消息可能会丧失。原因是当noAck=true 时,消息被发送后broker端就认为消息已经被接收,而消息可能会在发送过程中因为突发 的网络中断而未能到达消费者。在实际操作中,如果对消息丧失容忍度低,应该设置 noAck=false。6.12 流量控制RabbitMQ使用一个基于信用(credit-based)的算法来限制消息发布的速率。消息发 布者只有收到队列中所有镜像的credits才被允许发布消息。如果备队列没能产生credit 就会导致消息发布停止,直到收到所有的credits或者没能产生credit的备节点脱离集群 消息才会恢复发布。7用户访问控制当RabbitMQ server启动运行时,如果检测到它的数据库没有初始化或者被删除掉,它 会使用下面的资源初始化一个新的数据库:一个名字为的虚拟机一个默认密码为guest的guest账户,拥有虚拟机的全部访问权限。为了平安性,建议后续删除guest账户或者改变它的密码,尤其是broker会被公共访 问的情况下。7.1 "guest”账户连接限制guest账户默认是被禁止远程连接broker的,它只能通过本地回环接口(例如 localhost)连接broker。这在AMQP协议和通过插件开启的其他协议下都适用。而其他用 户那么不会被如此严格的限制。如果你希望用guest账户用远程访问broker,需要将loopback_users配置为口。如 下所示:rabbit, loopbackusers, .第19页,共18页保密级别:内部保密级别:内部编号占位符PaaS平台RabbitMQ服务开发指南访问权限检查当一个AMQP客户端连接到AMQP服务器时,它会指定将要进行操作的virtual hosto 此时RabbitMQ会执行一个一级访问控制,检查账户是否具有访问该virtual host的权限, 如果不具有,连接会被拒绝。像exchang、queues等资源都是在一个特定virtual host内的特定命名实体。在不 同的virtual hosts里相同的名字也代表不同的资源。因此当用户对资源进行操作时, RabbitMQ会执行一个二级访问检查。RabbitMQ对于用户对资源的configure、写和读等操作是分别对待的。configure操 作能够创立、删除资源或者改变资源的行为。写操作向资源中写入消息。读操作从资源中检 索消息。用户要想能够在资源上执行一个操作必须具有相应的权限。下表是AMQP命令的资源 访问权限表:AMQP commandconfigurewritereadexchange, declare(passive=false )exchangeexchange, declare(passive=true)exchange, declare(with AE)exchangeexchange (AE)exchangeexchange, deleteexchangequeue, declare(passive=false )queuequeue, declare(passive=true)queue, declare(with DLX)queueexchange(DLX)queuequeue, deletequeueexchange. bindexchange(destination)exchange(sour )exchange, unbindexchange(destination)exchange(sour )第20页,共18页queue, bindqueueexchangequeue, unbindqueueexchangebasic. publishexchangebasic, getqueuebasic.consumequeuebasic. purgequeue编号占位符PaaS平台RabbitMQ服务开发指南保密级别:内部RabbitMQ对用户访问每个vhost的权限控制通过一个三元的正那么表达式来进行,三 元分别表示configure、写和读。用户可以对名字匹配正那么表达式的资源有访问权限。需要 注意的是RabbitMQ中将AMQP未命名的默认exchange用amq. default来匹配。例如飞'表达式(空字符串等价于飞)仅能匹配空字符串,说明用户不能对资源 做任何操作。标准的AMQP资源都会以amq.作前缀,server产生的名字会议amq. gen做前缀。 例如'八(amq. gen. * | amq. default) $,就匹配所有server产生的名字还有默认的exchange。当一个AMQP客户端连接到AMQP服务器时,它会指定将要进行操作的virtual host。 此时RabbitMQ会执行一个一级访问控制,检查账户是否具有访问virtual host的权限,如 果不具有,连接会被拒绝。像exchang、queues等资源都是在一个特定virtual host内的特定命名实体。在不 同的virtual hosts里相同的名字也代表不同的资源。因此当用户对资源进行操作时, RabbitMQ会执行一个二级访问检查RabbitMQ对于用户对资源的configure、写和读等操作是分别对待的。configure操 作能够创立、删除资源或者改变资源的行为。写操作向资源中写入消息。读操作从资源中检 索消息。用户要想能够在资源上执行一个操作必须具有相应的权限。下表