随笔 - 41  文章 - 7  trackbacks - 0
<2016年8月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

原文:http://www.rabbitmq.com/configure.html

RabbitMQ 提供了三种方式来定制服务器:

环境变量
定义端口,文件位置和名称(接受shell输入,或者在环境配置文件(rabbitmq-env.conf)中设置)
配置文件
为服务器组件设置权限,限制和集群,也可以定义插件设置.
运行时参数和策略
可在运行时进行修改集群设置
大部分设置都使用前面的两种方法,但本指南会全部讲解.

验证配置(怎样找到配置文件地址)

有效配置文件可通过检查RabbitMQ日志文件进行验证.它会与其它中间件启动日志条目放置在日志文件 的顶部,例如:

node           : rabbit@example home dir       : /var/lib/rabbitmq config file(s) : /etc/rabbitmq/rabbitmq.config
如果找不到日志文件,日志将会显示:
node           : rabbit@example home dir       : /var/lib/rabbitmq config file(s) : /var/lib/rabbitmq/hare.config (not found)

定制RabbitMQ环境

可通过环境变量来配置服务器参数:节点名称, RabbitMQ 配置文件位置, AMQP 0-9-1 和节点通信端口等等.

Unix (general)

在基于Unix的系统(包含Linux, MacOSX)上,可以创建/编辑rabbitmq-env.conf来定义环境变量. 其位置是不可配置的(不像rabbitmq.config).

使用标准环境变量名称(去掉RABBITMQ_前辍) 如:

#example rabbitmq-env.conf file entries #Rename the node NODENAME=bunny@myhost #Config file location and new filename bunnies.config CONFIG_FILE=/etc/rabbitmq/testdir/bunnies
More info on using rabbitmq-env.conf

Windows

如果要在windows上配置名称,端口,位置,可通过在windows对话框来配置: Start > Settings > Control Panel > System > Advanced > Environment Variables.

创建或编辑系统变量名称和值.

要Windows上的环境变量生效,必须重新安装服务,光重启是不够的.这可以通过安装器或带有管理权限的命令行来完成:

  • 启动管理员命令提示窗口
  • 进入RabbitMQ服务器安装目录下的sbin目录 (e.g.C:\Program Files (x86)\RabbitMQ Server\rabbitmq_server-3.6.1\sbin)
  • 运行rabbitmq-service.bat remove
  • 通过命令行来设置环境变量,即像下面这样来运行命令:set RABBITMQ_BASE=c:\Data\RabbitMQ
  • 运行 rabbitmq-service.bat 来安装
另外,如果新配置需要在下次broker重启时生效,可跳过一个步骤 if new configuration needs to take effect after next broker restart, one step can be skipped:
  • 启动管理员命令提示窗口
  • 进入RabbitMQ服务器安装目录下的sbin目录
  • 通过命令行来设置环境变量
  • 运行 rabbitmq-service.bat 来安装, 这只会更新服务参数

RabbitMQ环境变量

RabbitMQ 环境变量有一个RABBITMQ_前辍. 典型的环境变量RABBITMQ_var_name是按下面进行设置的:

  • 如果在 shell环境变量中定义了名为RABBITMQ_var_name的变量,则优先使用此定义;
  • 否则,使用 rabbitmq-env.conf中变量名为var_name的定义;
  • 否则,使用系统指定的默认值.

这样,shell环境中的变量定义比rabbitmq-env.conf中的相同变量定义有更高的优先级, 而RabbitMQ中的系统默认值具有最低优先级.

你不太可能需要设置这些环境变量.如果你有非标准的需求,那么RabbitMQ环境变量包括但不限于下面的变量:

RABBITMQ_NODE_IP_ADDRESS
缺省
空字符串-意味着绑定到所有网络接口上.
描述
如果只想绑定到某个网络接口上,可修改此值. 如果要绑定两个以上的接口,需要在rabbitmq.config中使用tcp_listeners key.
RABBITMQ_NODE_PORT
缺省
5672
描述
RABBITMQ_DIST_PORT
缺省
RABBITMQ_NODE_PORT + 20000
描述
用于设置集群端口. 当在配置文件中设置了inet_dist_listen_min 或 inet_dist_listen_max时,此环境变量将被忽略

RABBITMQ_NODENAME
缺省
Unix*: rabbit@$HOSTNAME Windows:rabbit@%COMPUTERNAME%
描述
在每个erlang节点和机器的组合中,节点名称必须唯一. 要运行多个节点, 参考clustering guide.

RABBITMQ_CONF_ENV_FILE
缺省
  • Generic UNIX -$RABBITMQ_HOME/etc/rabbitmq/rabbitmq-env.conf
  • Debian - /etc/rabbitmq/rabbitmq-env.conf
  • RPM - /etc/rabbitmq/rabbitmq-env.conf
  • Mac OS X (Homebrew) -${install_prefix}/etc/rabbitmq/rabbitmq-env.conf, Homebrew 前辍通常是/usr/local
  • Windows -%APPDATA%\RabbitMQ\rabbitmq-env-conf.bat
描述
包含环境变量定义(无RABBITMQ_前辍)的文件位置.注意Window系统上的文件名称与其它操作系统上不同.


RABBITMQ_USE_LONGNAME
缺省
描述
当设置为 true时,这将导致RabbitMQ使用全限定名称来标识节点. 在EC2证实是有用的. 请注意,在没有重置节点的情况下,在长短名称之间切换是不可能的。

RABBITMQ_SERVICENAME
缺省
Windows Service: RabbitMQ
描述
安装服务的名称,这将显示在services.msc中

RABBITMQ_CONSOLE_LOG
缺省

描述
设置此变量为new或reuse,可将服务器控制台输出重定向到名为%RABBITMQ_SERVICENAME%.debug 的文件中,该文件默认位于RABBITMQ_BASE目录下.
  • 如果没有设置, 服务器控制台输出将被丢弃(默认情况).
  • new:服务每次启动时都会创建一个新文件.
  • reuse:每次服务启动的时候,文件都会被覆盖.

RABBITMQ_CTL_ERL_ARGS
缺省
描述
当在rabbitmqctl中调用erl命令时使用的参数.只在基于调试目的时,才可覆盖.

RABBITMQ_SERVER_ERL_ARGS
缺省
  • Unix*: "+K true +A30 +P 1048576 -kernel inet_default_connect_options [{nodelay,true}]"
  • Windows: None
描述
当调用RabbitMQ服务器时,在erl命令中使用的标准参数.只在基于调试目的时,才可覆盖.覆盖此变量将替换默认值.


RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS
缺省
  • Unix*: None
  • Windows: None
描述
当调用RabbitMQ服务器时,在erl命令中使用的其它参数.此变量的值会追加到默认参数列表之后(RABBITMQ_SERVER_ERL_ARGS).


RABBITMQ_SERVER_START_ARGS
缺省
None
描述
当调用RabbitMQ Server时,使用erl命令添加的其它参数.这不会覆盖RABBITMQ_SERVER_ERL_ARGS.
* Unix, Linux, MacOSX

此外,还有几个环境变量可用来告知RabbitMQ其数据库,日志文件,插件,配置文件的位置.

RabbitMQ依赖的变量有:


HOSTNAME

缺省

  • Unix, Linux: `env hostname`
  • MacOSX: `env hostname -s`

描述
当前机器的名称


COMPUTERNAME

缺省
  Windows: localhost
描述

当前机器的名称


ERLANG_SERVICE_MANAGER_PATH

缺省

Windows Service:%ERLANG_HOME%\erts-x.x.x\bin

描述

erlsrv.exe位置路径,Erlang服务的封装脚本

配置文件

rabbitmq.config 文件

rabbitmq.config配置文件允许配置RabbitMQ 核心程序, Erlang 服务和RabbitMQ 插件. 它是标准的Erlang 配置文件, 文档位于Erlang Config Man Page.

最小化的样例配置文件如下:

  [     {rabbit, [{tcp_listeners, [5673]}]}   ]. 

这个例子中将会修改RabbitMQ监听AMQP 0-9-1 客户端连接端口,5672修改为5673.

配置文件不同于环境配置文件rabbitmq-env.conf,(它可在非Window系统上设置环境变量).

rabbitmq.config 和 rabbitmq-env.conf的位置

这些文件的位置分布特定的. 默认情况下,这些文件是没有创建的,但每个平台上期望的位置如下:

  • Generic UNIX - $RABBITMQ_HOME/etc/rabbitmq/
  • Debian - /etc/rabbitmq/
  • RPM - /etc/rabbitmq/
  • Mac OS X (Homebrew) - ${install_prefix}/etc/rabbitmq/, the Homebrew prefix is usually/usr/local
  • Windows - %APPDATA%\RabbitMQ\

如果rabbitmq-env.conf不存在, 可在默认位置中手动创建. 它不能用于Windows系统.

如果rabbitmq.config不存在,可以手动创建它. 如果你修改了位置,可设置RABBITMQ_CONFIG_FILE 环境变量来指定. Erlang 运行时会自动在此变量值后添加.config扩展名,重启服务器后生效.

Windows 服务用户在删除配置文件后,需要重新安装服务.

示例rabbitmq.config文件

RabbitMQ server 源码仓库包含 一个示例配置文件 名为rabbitmq.config.example.这个示例文件中包含了你想要设置的大多数配置项(有一些省略)与其说明. 示例中的所有配置项都注释了的,如果你有需要,你可以取消注解. 注意,示例文件仅仅只是示例,不应该将其视为通用的推荐.

在大多数发行版中,我们将此示例文件放在真实文件的位置.然而再 Debian 和RPM 发行策略禁止这样做, 你可以在/usr/share/doc/rabbitmq-server/或 /usr/share/doc/rabbitmq-server-3.6.1/ respectively中找到.

rabbitmq.config中的变量配置

大部分的RabbitMQ用户都会不会修改这些值,有些是相当模糊的.然而,为了完整性,他们都在这里列出。

KeyDocumentation
tcp_listeners用于监听 AMQP连接的端口列表(无SSL). 可以包含整数 (即"监听所有接口")或者元组如 {"127.0.0.1", 5672} 用于监听一个或多个接口.

Default: [5672]

num_tcp_acceptors
接受TCP侦听器连接的Erlang进程数。

Default: 10

handshake_timeoutAMQP 0-8/0-9/0-9-1 handshake (在 socket 连接和SSL 握手之后)的最大时间, 毫秒为单位.

Default: 10000

ssl_listeners
如上所述,用于SSL连接。

Default: []

num_ssl_acceptors接受SSL侦听器连接的Erlang进程数。

Default: 1

ssl_optionsSSL配置.参考SSL documentation.

Default: []

ssl_handshake_timeoutSSL handshake超时时间,毫秒为单位.

Default: 5000

vm_memory_high_watermark流程控制触发的内存阀值.相看memory-based flow control 文档.

Default: 0.4

vm_memory_high_watermark_paging_ratio高水位限制的分数,当达到阀值时,队列中消息消息会转移到磁盘上以释放内存. 参考memory-based flow control 文档.

Default: 0.5

disk_free_limitRabbitMQ存储数据分区的可用磁盘空间限制.当可用空间值低于阀值时,流程控制将被触发. 此值可根据RAM的总大小来相对设置 (如.{mem_relative, 1.0}). 此值也可以设为整数(单位为bytes)或者使用数字单位(如."50MB"). 默认情况下,可用磁盘空间必须超过50MB. 参考 Disk Alarms 文档.

Default: 50000000

log_levels控制日志的粒度.其值是日志事件类别(category)和日志级别(level)成对的列表.

level 可以是 'none' (不记录日志事件), 'error' (只记录错误), 'warning' (只记录错误和警告), 'info' (记录错误,警告和信息), or 'debug' (记录错误,警告,信息以及调试信息).

目前定义了4种日志类别. 它们是:

  • channel -针对所有与AMQP channels相关的事件
  • connection - 针对所有与网络连接相关的事件
  • federation - 针对所有与federation相关的事件
  • mirroring -针对所有与 mirrored queues相关的事件

Default: [{connection, info}]

frame_max与客户端协商的允许最大frame大小. 设置为0表示无限制,但在某些QPid客户端会引发bug. 设置较大的值可以提高吞吐量;设置一个较小的值可能会提高延迟.

Default: 131072

channel_max与客户端协商的允许最大chanel大小. 设置为0表示无限制.该数值越大,则broker使用的内存就越高.

Default: 0

channel_operation_timeoutChannel 操作超时时间(毫秒为单位) (内部使用,因为消息协议的区别和限制,不暴露给客户端).

Default: 5000

heartbeat表示心跳延迟(单位为秒) ,服务器将在connection.tune frame中发送.如果设置为 0, 心跳将被禁用. 客户端可以不用遵循服务器的建议, 查看 AMQP reference 来了解详情. 禁用心跳可以在有大量连接的场景中提高性能,但可能会造成关闭了非活动连接的网络设备上的连接落下.

Default: 60 (3.5.5之前的版本是580)

default_vhost当RabbitMQ从头开始创建数据库时创建的虚拟主机. amq.rabbitmq.log交换器会存在于这个虚拟主机中.

Default: <<"/">>

default_userRabbitMQ从头开始创建数据库时,创建的用户名.

Default: <<"guest">>

default_pass默认用户的密码.

Default: <<"guest">>

default_user_tags默认用户的Tags.

Default: [administrator]

default_permissions创建用户时分配给它的默认Permissions .

Default: [<<".*">>, <<".*">>, <<".*">>]

loopback_users只能通过环回接口(即localhost)连接broker的用户列表

如果你希望默认的guest用户能远程连接,你必须将其修改为[].

Default: [<<"guest">>]

cluster_nodes当节点第一次启动的时候,设置此选项会导致集群动作自动发生. 元组的第一个元素是其它节点想与其建立集群的节点. 第二个元素是节点的类型,要么是disc,要么是ram

Default: {[], disc}

server_properties连接时向客户端声明的键值对列表

Default: []

collect_statistics
统计收集模式。主要与管理插件相关。选项:
  • none (不发出统计事件)
  • coarse (发出每个队列 /每个通道 /每个连接的统计事件)
  • fine (也发出每个消息统计事件)
你自已可不用修改此选项.

Default: none

collect_statistics_interval统计收集时间间隔(毫秒为单位). 主要针对于 management plugin.

Default: 5000

auth_mechanisms提供给客户端的SASL authentication mechanisms.

Default: ['PLAIN', 'AMQPLAIN']

auth_backends

用于 authentication / authorisation backends 的列表. 此列表可包含模块的名称(在模块相同的情况下,将同时用于认证来授权)或像{ModN, ModZ}这样的元组,在这里ModN将用于认证,ModZ将用于授权.

在2元组的情况中, ModZ可由列表代替,列表中的所有元素必须通过每个授权的确认,如{ModN, [ModZ1, ModZ2]}. 这就允许授权插件进行组合提供额外的安全约束.

rabbit_auth_backend_internal外,其它数据库可以通常 plugins来使用.

Default: [rabbit_auth_backend_internal]

reverse_dns_lookups设置为true,可让客户端在连接时让RabbitMQ 执行一个反向DNS查找, 然后通过 rabbitmqctl 和 管理插件来展现信息.

Default: false

delegate_count内部集群通信中,委派进程的数目. 在一个有非常多核的机器(集群的一部分)上,你可以增加此值.

Default: 16

trace_vhosts tracer内部使用. 你不应该修改.

Default: []

tcp_listen_options默认socket选项. 你可能不想修改这个选项.

Default:

[{backlog,       128},          {nodelay,       true},          {exit_on_close, false}]
hipe_compile将此选项设置为true,将会使用HiPE预编译部分RabbitMQ,Erlang的即时编译器.
这可以增加服务器吞吐量,但会增加服务器的启动时间.
你可以看到花费几分钟延迟启动的成本,就可以带来20-50% 更好性能.这些数字与高度依赖于工作负载和硬件.

HiPE 支持可能没有编译进你的Erlang安装中.如果没有的话,启用这个选项,并启动RabbitMQ时,会看到警告消息. 例如, Debian / Ubuntu 用户需要安装erlang-base-hipe 包.

HiPE并非在所有平台上都可用, 尤其是Windows.

在 Erlang/OTP 17.5版本之前,HiPE有明显的问题 . 对于HiPE,使用最新的OTP版本是高度推荐的.

Default: false

cluster_partition_handling如何处理网络分区.可用模式有:
  • ignore
  • pause_minority
  • {pause_if_all_down, [nodes], ignore | autoheal}where [nodes] is a list of node names
    (ex: ['rabbit@node1', 'rabbit@node2'])
  • autoheal
参考documentation on partitions 来了解更多信息

Default: ignore

cluster_keepalive_interval节点向其它节点发送存活消息和频率(毫秒). 注意,这与 net_ticktime是不同的; 丢失存活消息不会引起节点掉线

Default: 10000

queue_index_embed_msgs_below消息大小在此之下的会直接内嵌在队列索引中. 在修改此值时,建议你先阅读  persister tuning 文档.

Default: 4096

msg_store_index_module队列索引的实现模块. 在修改此值时,建议你先阅读  persister tuning 文档.

Default: rabbit_msg_store_ets_index

backing_queue_module队列内容的实现模块. 你可能不想修改此值.

Default: rabbit_variable_queue

msg_store_file_size_limitTunable value for the persister. 你几乎肯定不应该改变此值。

Default: 16777216

mnesia_table_loading_timeout
在集群中等待使用Mnesia表可用的超时时间。

Default: 30000

queue_index_max_ journal_entriesTunable value for the persister. 你几乎肯定不应该改变此值。

Default: 65536

queue_master_locatorQueue master 位置策略. 可用策略有:
  • <<"min-masters">>
  • <<"client-local">>
  • <<"random">>
查看documentation on queue master location 来了解更多信息.

Default: <<"client-local">>

此外,许多插件也可以在配置文件中配置, 其名称是rabbitmq_plugin的形式我们的维护的插件被记录在以下位置:

文件位置

你可以设置下面的环境变量来指定相关文件的位置,但大部分人都不必这样做:

名称描述
RABBITMQ_BASE此基础目录包含了RabbitMQ server的数据库,日志文件的子目录. 另外,也可以独立设置RABBITMQ_MNESIA_BASE 和 RABBITMQ_LOG_BASE 目录.
RABBITMQ_CONFIG_FILE用于配置文件的路径,无.config扩展名. 如果 configuration file 存在,服务器将使用它来配置RabbitMQ组件. 参考 Configuration guide 来了解更多信息.
RABBITMQ_MNESIA_BASE包含RabbitMQ 服务器Mnesia数据库文件子目录的基本目录,除非明确设置了RABBITMQ_MNESIA_DIR目录,否则每个节点都应该配置一个. (除了Mnesia文件,这个位置还包含消息存储和索引文件以及模式和集群的细节.)
RABBITMQ_MNESIA_DIRRabbitMQ节点Mnesia数据库文件安放的目录. (除了Mnesia文件,这个位置还包含消息存储和索引文件以及模式和集群的细节.)
RABBITMQ_LOG_BASE用于包含RabbitMQ 服务器日志文件的基本目录, 除非明确设置了RABBITMQ_LOGS 或 RABBITMQ_SASL_LOGS.
RABBITMQ_LOGSRabbitMQ 服务器的Erlang日志文件路径.在Window上不能覆盖此变量.
RABBITMQ_SASL_LOGSRabbitMQ服务器的Erlang SASL (System Application Support Libraries)日志文件路径. 在Window上不能覆盖此变量.
RABBITMQ_PLUGINS_DIR用于查找插件目录 .
RABBITMQ_PLUGINS_EXPAND_DIR
用于在启动服务器时扩展启用插件的工作目录。
RABBITMQ_ENABLED_PLUGINS_FILE
此文件记录了显式启用的插件。
RABBITMQ_PID_FILE此文件中包含了rabbitmqctl所等待进程ID的信息.

Unix 默认位置

在下面的表格中,${install_prefix}表示某个路径. Homebrew 安装时使用installation-prefix (Homebrew Cellar) . 默认是/usr/local.

Deb / RPM 包安装使用空${install_prefix}.

NameLocation
RABBITMQ_BASE(Not used)
RABBITMQ_CONFIG_FILE${install_prefix}/etc/rabbitmq/rabbitmq
RABBITMQ_MNESIA_BASE${install_prefix}/var/lib/rabbitmq/mnesia
RABBITMQ_MNESIA_DIR$RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME
RABBITMQ_LOG_BASE${install_prefix}/var/log/rabbitmq
RABBITMQ_LOGS$RABBITMQ_LOG_BASE/$RABBITMQ_NODENAME.log
RABBITMQ_SASL_LOGS$RABBITMQ_LOG_BASE/$RABBITMQ_NODENAME-sasl.log
RABBITMQ_PLUGINS_DIR$RABBITMQ_HOME/plugins
RABBITMQ_PLUGINS_EXPAND_DIR$RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME-plugins-expand
RABBITMQ_ENABLED_PLUGINS_FILE${install_prefix}/etc/rabbitmq/enabled_plugins
RABBITMQ_PID_FILE$RABBITMQ_MNESIA_DIR.pid

Windows 默认位置

NameLocation
RABBITMQ_BASE%APPDATA%\RabbitMQ
RABBITMQ_CONFIG_FILE%RABBITMQ_BASE%\rabbitmq
RABBITMQ_MNESIA_BASE%RABBITMQ_BASE%\db
RABBITMQ_MNESIA_DIR%RABBITMQ_MNESIA_BASE%\%RABBITMQ_NODENAME%
RABBITMQ_LOG_BASE%RABBITMQ_BASE%\log
RABBITMQ_LOGS%RABBITMQ_LOG_BASE%\%RABBITMQ_NODENAME%.log
RABBITMQ_SASL_LOGS%RABBITMQ_LOG_BASE%\%RABBITMQ_NODENAME%-sasl.log
RABBITMQ_PLUGINS_DIRInstallation-directory/plugins
RABBITMQ_PLUGINS_EXPAND_DIR%RABBITMQ_MNESIA_BASE%\%RABBITMQ_NODENAME%-plugins-expand
RABBITMQ_ENABLED_PLUGINS_FILE%RABBITMQ_BASE%\enabled_plugins
RABBITMQ_PID_FILE(Not currently supported)

通用UNIX默认位置

当解压Generic Unix tar文件并运行时,由于默认获得到位置,不需要进行. 在下面的表格中,$RABBITMQ_HOME指的是rabbitmq_server-3.6.1 解压后的目录

NameLocation
RABBITMQ_BASE(Not used)
RABBITMQ_CONFIG_FILE$RABBITMQ_HOME/etc/rabbitmq/rabbitmq
RABBITMQ_MNESIA_BASE$RABBITMQ_HOME/var/lib/rabbitmq/mnesia
RABBITMQ_MNESIA_DIR$RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME
RABBITMQ_LOG_BASE$RABBITMQ_HOME/var/log/rabbitmq
RABBITMQ_LOGS$RABBITMQ_LOG_BASE/$RABBITMQ_NODENAME.log
RABBITMQ_SASL_LOGS$RABBITMQ_LOG_BASE/$RABBITMQ_NODENAME-sasl.log
RABBITMQ_PLUGINS_DIR$RABBITMQ_HOME/plugins
RABBITMQ_PLUGINS_EXPAND_DIR$RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME-plugins-expand
RABBITMQ_ENABLED_PLUGINS_FILE$RABBITMQ_HOME/etc/rabbitmq/enabled_plugins
RABBITMQ_PID_FILE$RABBITMQ_MNESIA_DIR.pid


持久化配置

RabbitMQ持久层的目的是为了得到好的结果,在大多数情况下没有配置。然而,一些配置有时是有用的。此页解释了如何配置它。在采取任何行动之前,你都应该阅读这一切。

持久化如何工作

首先,先讲一下背景: 持久化和短暂消息都可以写入磁盘.持久化消息一旦到达队列,就会写入磁盘,而短暂消息只在内存压力较大被赶出内存时才会写入磁盘.持久化消息在内存紧张释放内存时,依然也会存在内存中. 持久层指的是存储这两种类型消息到磁盘的机制.


在本页中,我们说的队列是指无镜像队列或master队列或slave队列. 队列镜像会发生以上的持久化.

持久层有两个组件: 队列索引和消息存储.队列索引负责维护消息在队列的位置,以及是否被投递,是否应答的信息. 因此,每个队列都有一个队列索引。

消息存储是消息的key-value存储, 由服务器中的所有队列共享.消息(消息体, 消息属性或消息头)可直接存储于队列索引,也可以写到消息存储中.在技术上有两个消息存储(一个暂时的和一个持久的消息),但他们通常一起被被认为是“消息存储”。

内存成本

在内存压力下,持久层试图尽可能多地写入磁盘,并尽可能的从内存中删除。然而有一些事情必须留在内存中:
  • 每个队列都会为每个未应答消息维护一些元数据.如果它的目的地是消息存储,则消息本身可以从内存中删除。
  • 消息存储需要索引. 默认消息存储索引对于存储中的每个消息会使用少量内存.

队列索引中的消息

将消息写入队列索引有优点也有缺点.

优点:

  • 消息可在一个操作中(而不是两个)写入磁盘; 对于微小的消息,这可以是一个实质性的增益.
  • 写入队列索引的消息不需要消息存储索引中的条目,因此当页出(paged out)时,不需要花费内存成本.

缺点:

  • 队列索引在内存中保有固定数量的记录块;如果写入队列索引中的消息不是小消息,那么内存占用也是巨大的.
  • 如果一个消息通过一个交换路由到多个队列,则消息将需要写入多个队列索引。如果这样的消息被写入消息存储区,则只有一个副本需要被写入。
  • 目的地是队列索引的未应答消息总会保存在内存中.

将小消息存储在队列索引中目的是优化,所有其它消息将会写入消息存储.这可以配置项queue_index_embed_msgs_below来配置.默认情况下,序列后大小小于4096字节 (包括属性和头)会存储在队列索引中.

当从磁盘中读取消息时,每个队列索引至少需要在内存中保留一个段文件(segment file). 段文件中包含了16,384个消息. 因此要谨慎如果增加queue_index_embed_msgs_below;小的增加会导致大量的内存使用。

无意中有限的持久性能(Accidentally limited persister performance)

持久化有可能表现不佳,因为持久化受限于文件句柄的数目或与它工作的异步线程.在这两种情况下,当您有大量需要同时访问磁盘的队列时,会发生这样的情况。.

太少的文件句柄

RabbitMQ 服务器通常受限于它能打开的文件句柄数量(在Unix上,无论如何). 每个运行的网络连接都需要一个文件句柄, 其余的可用于队列使用。如果磁盘访问队列比考虑到网络连接后文件句柄更多,那么磁盘访问队列将与文件句柄一起共享; 每个都会在它返回交给另一个队列之前,都会使用文件句柄一段时间.

当有太多磁盘访问队列时,这可以防止服务器崩溃,但代价是昂贵的. 管理插件可以显示集群中每个节点的统计I/O统计信息,如读,写,查找的速率.同时它也会显示重新开始(reopens)的速率- 文件句柄通过这种方式来回收利用. 一个有太少文件句柄繁忙的服务器每秒可能会做几百次reopens - 在这种情况下,如果增加文件句柄,就有可能提高性能.

太少的异步线程

Erlang 虚拟机创建异步线程池来处理长时间运行的文件I/O操作. 这些线程池是所有队列所共享的.每个活跃的文件I/O操作都会使用一个异步线程. 太少的异步线程可以因此伤害性能。

注意,异步线程的情况并不完全类似与文件句柄的情况. 如果一个队列按顺序来执行一定数量的I/O操作,假设它持有一个文件句柄来所理所有操作,其性能是最好的,否则,我们会占用CPU来做更多的刷新,查找 操作. 然而,队列不能从持有一个异步线程执行一系列的操作中获益(事实上也做不到).

因此理论上应该要有足够的文件句柄来处理所有队列上的I/O流操作, 并且要有足够的线程来处理并发的 (simultaneous )的I/O操作.

由异步线程缺乏造成的性能问题,不是太明显. (一般情况下都不太可能,可首先检查其它地方!) .

太少异步线程的典型症状是,当服务器忙于持久化时,在很短的时间内,每秒 I/O操作的数目将会下降到0(管理插件可报告) ,报告的每个 I/O操作的时间将会增加.

Erlang虚拟主机的异步线程数目可通过+A 参数进行配置,这里有描述, 通常情况下,也可以通过环境变量RABBITMQ_SERVER_ERL_ARGS来配置. 默认值是 +A 30. 在修改之前,多进行几次尝试总是好主意.


网络与RabbitMQ

介绍

网络是Clients与RabbitMQ通信的媒介.broker支持的所有协议都是基于TCP的. RabbitMQ 和操作系统都提供了许多可调整的旋钮.其中,有些是直接与TCP和IP操作相关的,其它则是与应用程序级协议如TLS相关的. 本指南涵盖了RabbitMQ中与网络相关的多个主题. 本指南并不是一广泛的指南,而只是一个概述. 某些调整参数是与特定操作系统相关的.当有与特定操作系统相关的主题时, 本指南只关注Linux,因为它是部署RabbitMQ的最常见平台.

有几个可以配置或调整的区域:
  • 网络接口和端口
  • TLS
  • TCP socket 设置
  • Kernel TCP 设置
  • (AMQP 0-9-1, STOMP) Heartbeats
  • Hostnames and DNS
除了OS kernel参数和DNS,所有RabbitMQ设置都可以 采用同种方式来配置.
网络是一个广泛的话题。有许多配置选项,可以对某些工作负载产生积极或消极的影响。因此,本指南不尝试是一个完整的参考,而是提供一个关键的可调参数的索引,并作为一个起点。

网络接口

RabbitMQ用于接受客户端连接,它需要绑定一个或多个网络接口,并监听特定的端口. 网络接口使用rabbit.tcp_listeners选项来配置.默认情况下,RabbitMQ会在所有可用网络接口上监听5672端口.

TCP listeners 可配置网络接口和端口. 下面的示例演示了如何在一个特定网络接口和端口上进行监听:

[   {rabbit, [     {tcp_listeners, [{"192.168.1.99", 5672}]}   ]} ]. 

在双协议栈上(IPv4和IPv6)接口上监听

下面的例子演示了如何在IPv4 and IPv6上进行监听:

[   {rabbit, [     {tcp_listeners, [{"127.0.0.1", 5672},                      {"::1",       5672}]}   ]} ]. 

现代Linux kernels 以及Vista后的Windows版本,当在所有IPv6地址上配置端口时,IPv4是没有明确禁用的,IPv4地址依然可用,因此

[   {rabbit, [     {tcp_listeners, [{"::",       5672}]}   ]} ]. 
等价于
[   {rabbit, [     {tcp_listeners, [{"0.0.0.0", 5672},                      {"::",      5672}]}   ]} ]. 

只监听IPv4接口

在这个例子中,RabbitMQ只会监听IPv4接口:

[   {rabbit, [     {tcp_listeners, [{"192.168.1.99", 5672}]}   ]} ]. 

此外,如果只希望有单个stack设置, 可使用RABBITMQ_NODE_IP环境变量来配置. 参考 Configuration guide 来了解细节.

只监听IPv6接口

在这个例子中,RabbitMQ会只监听IPv6接口:

[   {rabbit, [     {tcp_listeners, [{"fe80::2acf:e9ff:fe17:f97b", 5672}]}   ]} ]. 

此外,如果只希望有单个stack设置, 可使用RABBITMQ_NODE_IP环境变量来配置. 参考 Configuration guide 来了解细节.

端口访问

SELinux 以及相似的机制可能会阻止RabbitMQ绑定到某个端口. 当这样的情况发生时,RabbitMQ启动会失败.必须保证可打开下面的端口:

  • 4369 (epmd), 25672 (Erlang distribution)
  • 5672, 5671 (AMQP 0-9-1无或有TLS)
  • 15672 (如果启用了管理插件)
  • 61613, 61614 (如果启用了STOMP)
  • 1883, 8883 (如果启用了MQTT)
也可以通过配置configure RabbitMQ 来使用不同的端口.

在RabbitMQ中可使用TLS来加密. 使用对等证书的身份验证也是可能的。请参阅TLS / SSL的更多信息指南。

优化吞吐量

优化吞吐量是一个共同的目录. 可通过下面的来实现

  • 增大TCP 缓冲区大小
  • 确保Nagle的算法失效
  • 启用可选TCP功能和扩展
对于后两个,可看下面的操作系统级别调整部分。请注意,调整吞吐量将涉及权衡问题。例如,增加TCP缓冲区的大小会增加每一个连接的内存使用数量,从而使得总服务器内存增大。

TCP缓冲区大小

这是关键的调整参数. 每个TCP连接都分配了缓冲区. 一般来说,缓冲区用得越大,每个连接上RAM就用得越多,就有更好的吞吐率.在Linux,操作系统默认会自动调整TCP缓冲区的大小,通常会设置为80到120 KB之间.要获取最大吞吐量,可使用rabbit.tcp_listen_options来加大配置.

下面的例子将TCP缓冲区设置为192 KiB:

[   {rabbit, [   {tcp_listen_options, [                         {backlog,   128},                         {nodelay,   true},                         {sndbuf,    196608},                         {recbuf,    196608}                        ]}   ]} ]. 
注意,将发发送缓冲区和接收缓冲区设置不同的值是很危险的,且是不推荐的.

Erlang 虚拟机I/O线程池

Erlang 运行时使用线程池来异步执行I/O操作. 池的大小可通过+A VM命令行标志来配置,如+A 128. 我们强烈建议使用`RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS`环境变量来覆盖此选项:

RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="+A 128" 
默认值为30. 8个或8个以上的节点建议使用高于96的值,即: 每核上可以运行12或12以上的I/O线程. 注意:值越高不意味着有更好的吞吐量或由于等待的I / O 而造成较低的处理器烧伤.

优化大量连接

有多个因素可以限制单个节点上支持的并发连接数:

  • 可打开的最大文件句柄数目,以及其它kernel强制的资源限制
  • 每个连接使用的RAM数量
  • 每个连接使用的CPU资源数目
  • VM中配置的最大Erlang进程数目

打开文件句柄限制

大部分操作系统都限制了同一时间可以打开的文件句柄数目. 限制是如何配置的 每个操作系统上都不同.

当在优化并发连接数的时候,须确保你的系统有足够的文件描述符来支持你的client和节点的使用. 

要粗略地计算限制,可以用每个节点上连接的数目乘以1.5. 例如,要支持100,000个连接,需要设置限制文件描述符为150,000.稍为增加限制可增加闲置机器内存的使用量,但这是一个合理的权衡。

TCP 缓冲区大小

见上文的部分概述. 可使用rabbit.tcp_listen_options选项来减小缓冲区大小,这样就可以减小每个连接上使用的RAM使用量. 在每个节点上的并发量比吞吐量重要的环境中,这通常是必须的.

下面的例子将TCP缓冲区设置为32 KiB:

[   {rabbit, [     {tcp_listen_options, [                           {backlog,   128},                           {nodelay,   true},                           {sndbuf,    32768},                           {recbuf,    32768}                          ]}   ]} ]. 
注意,越小的TCP缓冲区会导致明显的吞吐量下降, 所以最优的值可在吞吐量和每连接使用的RAM值中找到 ,即在它们之间作一个权衡.将发送缓冲区和接收缓冲区的值设为不同,这是非常危险的且是不推荐的.低于8 KiB的值是不推荐的.

Nagle's 算法 ("nodelay")

禁用Nagle的算法主要对于减少延迟有用,同时也可以改善throughput.kernel.inet_default_connect_options和kernel.inet_default_listen_options.必须在节点间的连接包括{nodelay,true},禁用Nagle的算法。当配置服务客户端连接的socket时,rabbit.tcp_listen_options必须包含相同的选项。这是默认值。下面的示例演示这种情况:
[   {kernel, [     {inet_default_connect_options, [{nodelay, true}]},     {inet_default_listen_options,  [{nodelay, true}]}   ]},   {rabbit, [     {tcp_listen_options, [                           {backlog,   4096},                           {nodelay,   true}                          ]}   ]} ]. 

Erlang虚拟机I/O线程池优化

当优化大量并发连接数时,恰当的Erlang虚拟机I/O线程池大小也很重要。见上面的部分。

连接积压(Backlog)

当只有较少数量的客户端时,新连接的分布是非常不均匀的,但因为足够小,所以没有太大的差异当数量达到数万或更多时,重要的是要确保服务器可以接受入站连接.未接受的TCP连接会放在带有限制长度的队列中. 此长度必须能应对负载较小和较高时的情况,例如,当许多客户端因为网络中断或重连时,必须能应对. 

这可以通过rabbit.tcp_listen_options.backlog选项来配置:

[   {rabbit, [     {tcp_listen_options, [                           {backlog,   4096},                           {nodelay,   true}                          ]}   ]} ]. 
默认值是128. 当挂起的连接队列长度超出此值时,连接将被操作系统拒绝。也可参见优化内核部分的net.core.somaxconn。

操作系统级别的调整

操作系统设置可影响RabbitMQ的操作.有些是直接与网络相关的(如. TCP设置),其它影响是TCP sockets以及其它东西(如打开文件句柄的限制).理解这些限制是很重要的,因为随着工作量不同而改变.

几个重要的可配置内核选项包括 (针对IPv4):

fs.file-max
            内核将分配的最大数量的文件. 极限和当前值可通过使用/proc/sys/fs/file-nr检查.
net.ipv4.ip_local_port_range
本地IP端口范围,定义为一对值。该范围必须为并发连接的峰值数提供足够的条目。
net.ipv4.tcp_tw_reuse
当启用时,允许内核重用TIME_WAIT状态的sockets.参考Coping with the TCP TIME_WAIT connections on busy servers 来了解细节. 当用在NAT时,此选项是很危险的.
net.ipv4.tcp_fin_timeout
降低此值到5-10 可减少连接关闭的时间,之后会停留在TIME_WAIT状态.建议用在有大量并发连接的场景.
net.core.somaxconn
监听队列的大小(同一时间建立过程中有多少个连接). 默认是128. 增大到4096或更高,可以支持入站连接的爆发,如clients集体重连.
net.ipv4.tcp_max_syn_backlog
尚未收到连接客户端确认的连接请求的最大数量。默认为128,最大值为65535。优化吞吐量时,4096和8192是推荐的起始值。
net.ipv4.tcp_keepalive_*
net.ipv4.tcp_keepalive_timenet.ipv4.tcp_keepalive_intvl,net.ipv4.tcp_keepalive_probes 用于配置TCP存活时间. AMQP 0-9-1 和 STOMP有Heartbeats ,这部分撤销了其效果,换句话说,它可以花几分钟来探测未响应的同等端,如:硬件或掉电故障. 当启用了TCP keepalive,我们建议设置心跳超时为8-20秒.
net.ipv4.conf.default.rp_filter
启用反向地址过滤. 如果你的系统不关心IP地址欺骗 ,那么就禁用它.
请注意,这些默认值在不同的内核版本和发行版之间是不同的。使用最近的内核(3.9或更新)。

内核参数调整在不同操作系统之间是不同的.这篇指南针对的是Linux. 配置内核参数交互,使用sysctl -w (需要超级权限),例如:

sysctl -w fs.file-max 200000 
要使修改永久生效,需要将它产加到 /etc/sysctl.conf. 参考sysctl(8) 和 sysctl.conf(5) 来了解细节.
TCP协议栈调整是一个广泛的话题,其他地方有详细的介绍:

TCP Socket 选项

通用选项

rabbit.tcp_listen_options.nodelay

当设置为true,可禁用Nagle算法.默认为true. 高度推荐给大多数用户。
rabbit.tcp_listen_options.sndbuf
参考本指南先前讨论的TCP缓冲区. 默认值自动由操作系统高速,在现代Linux版本上,通常是88 KiB 到 128 KiB的范围.增大缓冲区可以提高消费者的吞吐量,同时也会加大每个连接上的RAM使用量.减小会有相反的效果.
rabbit.tcp_listen_options.recbuf
参考本指南先前讨论的TCP缓冲区. 默认值的效果类似于rabbit.tcp_listen_options.sndbuf ,但这里一般针对的是发布者或协议操作.
rabbit.tcp_listen_options.backlog
队列中未接受连接的最大数目.当达到此大小时,新连接会被拒绝. 对于成千上万的并发连接环境以及可能存在大量客户重新连接的场景,可设为4096或更高.
rabbit.tcp_listen_options.linger
当设置为{true, N},当socket关闭时,用于设置刷新未发送数据的超时时间(秒为单位)
rabbit.tcp_listen_options.keepalive
当设置为true,将启用TCP keepalives (查看上面的章节). 默认为false.对于连接长时间空闲(至少10分钟)的环境来说是有意义的, 尽管更推荐使用heartbeats 选项.

缺省

下面是RabbitMQ使用的默认TCP socket选项:

[   {rabbit, [     {tcp_listen_options, [{backlog,       128},                           {nodelay,       true},                           {linger,        {true, 0}}]}   ]} ]. 

心跳(Heartbeats)

RabbitMQ支持某些协议, 包括AMQP 0-9-1, 支持心跳,一种更多快速探测死亡 TCP对等端的方法. 请参考 Heartbeats guide 来了解更多信息.

Net Tick Time

Heartbeats 用于探测客户端与RabbitMQ之间的对等端或连接故障 .net_ticktime 也有同样的目的,但它针对的是集群节点通信. 低于5(秒)的值可能会导致负面影响,不建议使用。

连接握手超时(Connection Handshake Timeout)

RabbitMQ有连接握手超时时间,默认为10秒钟. 当客户端在严重受限的环境中运行时,可能需要增加超时时间。这可以通过rabbit.handshake_timeout(毫秒)来完成:

[   {rabbit, [     %% 20 seconds     {handshake_timeout, 20000}   ]} ]. 
应该指出的是,这只在客户端和网络有严格约束的情况下使用。握手超时在其他情况下也会出现问题。

TLS/SSL Handshake

如果启用了TLS/SSL,也有必要增大TLS/SSL握手超时时间. 这可以通过rabbit.ssl_handshake_timeout (毫秒)来完成:

[   {rabbit, [     %% 10 seconds     {ssl_handshake_timeout, 10000}   ]} ]. 

主机名解析和DNS

在许多情况下,RabbitMQ依靠Erlang运行时节点间通信(包括工具rabbitmqctl,RabbitMQ插件等)。当客户端进行连接RabbitMQ节点时,客户端包会执行主机名解析。本节简要介绍了与此相关的最常见问题。

Client Libraries执行

如果client library配置成用主机名进行连接,它会执行主机名解析.依赖于 DNS 和本地解析器(类似于/etc/hosts)配置,这可能会花点时间.错误配置可能会导致解析超时,如,当试图通过DNS解析本地主机名如my-dev-machine. 其结果是,客户端连接会花很长的时候(几十秒到几分钟).

简短的和全限定RabbitMQ节点名称

RabbitMQ 依赖于Erlang运行时来进行节点间通信. Erlang节点包括主机名,要么是短的 (rmq1) 要么是全限定的(rmq1.dev.megacorp.local). 混合使用简短的和全限定的节点名称,是运行时不允许的 .集群中的每个节点必须能够解析其它节点的主机名, 简短的和全限定的. 默认情况下,RabbitMQ 会使用简短主机名. 设置RABBITMQ_USE_LONGNAME 环境变量可以开启使用全限定节点名称如.rmq1.dev.megacorp.local.

反向DNS查找

如果rabbit.reverse_dns_lookups 配置选项设为了true, RabbitMQ会为客户端IP地址执行反向DNS查找,并在connection中列出主机名称 (如,在Management UI).

参数和策略

介绍

跃然RabbitMQ大部分配置都生活在configuration file, 有些东西却不能在配置文件中配置:

  • 如果他们需要在一个集群中的所有节点是相同的
  • 如果他们有可能在运行时改变

RabbitMQ 称这些项为参数. 参数可通过调用rabbitmqctl 或通过the management plugin 的HTTP API来设置. 参数的scope是基于虚拟主机(vhost)的.

参数特殊的使用情况是策略( policies),它用于为成组的队列和交换器,以及插件(如Federation 和 Shovel)指定可选参数.

参数管理

参数可以被设置,清除,和列举:

rabbitmqctlrabbitmqctl set_parameter {-p vhostcomponent_name name value
rabbitmqctl clear_parameter {-p vhostcomponent_name name
rabbitmqctl list_parameters {-p vhost}
HTTP APIPUT /api/parameters/component_name/vhost/name
DELETE /api/parameters/component_name/vhost/name
GET /api/parameters

由于参数值是一个JSON文档, 当在使用rabbitmqctl命令行创建时,你通常需要引用它. 在Unix上,很容易使用单引号来引用整个文档,在其中可以使用双引号.在Windows上,你必须转义所有双引号.基于此理由,我们为Unix和Windows分别给出了例子.

RabbitMQ使用数据库中的参数来定义虚拟主机,交换器,队列,绑定,用户和权限. 参数是通过管理插件的导出功能以及对象定义中导出的.

federation 和 shovel 插件会使用参数.

策略(Policies)

策略会自动匹配交换器和队列,并帮助确定他们的行为. 每个交换器和队列至少有一个策略匹配,并且每个策略都会在交换器或队列上映射一系列的key-value对.

策略的行为有点像exchange.declare和queue.declare的参数, 除了它们会自动应用(不需要客户端程序的干预),并且它们可在任何时候进行修改.请注意,策略控制的功能集合与参数控制的功能集合是不同的.

策略会在每次交换器或队列创建的时候进行匹配,而不仅仅是在创建策略时。 

策略可用来配置 federation pluginmirrored queuesalternate exchangesdead letteringper-queue TTLs, 以及maximum queue length.

策略定义如下:

rabbitmqctl

rabbitmqctl set_policy federate-me "^amq\." '{"federation-upstream-set":"all"}' --priority 1 --apply-to exchanges
rabbitmqctl (Windows)

 

rabbitmqctl set_policy federate-me "^amq\." "{""federation-upstream-set"":""all""}" --priority 1 --apply-to exchanges
HTTP API

 

PUT /api/policies/%2f/federate-me {"pattern": "^amq\.",  "definition": {"federation-upstream-set":"all"},  "priority": 1,  "apply-to": "exchanges"}
Web UI

 

  • Navigate to Admin > Policies > Add / update a policy.
  • Enter "federate-me" next to Name, "^amq\." next to Pattern, and select "Exchanges" next to Apply to.
  • Enter "federation-upstream-set" = "all" in the first line next to Policy.
  • Click Add policy.


键"federation-upstream-set"的值为"all",这将匹配虚拟主机"/"中的所有名称以"amq."开头的交换器.

"pattern" 参数是一个用来匹配交换器或队列名称的正则表达式.

当有多个策略匹配交换器或队列时,则会应用优先级最高的策略.

"apply-to" 参数值可以是"exchanges""queues" 或"all""apply-to" 和 "priority"设置是可选的, 在这种情况下,其默认值是"all"和"0".

组合策略定义

在某些情况下,我们想要在资源上应用多个策略.例如,我们想让一个队列能同时联合和镜像. 任何时候,在资源上最多只能应用一个策略,但我们可在那个策略中应用多个定义.

联合(federation)策略定义需要指定一个upstream 集合,因此在我们的定义中,我们需要federation-upstream-set 键.另一方面,要镜像队列,我们需要在策略中定义ha-mode键.由于策略定义只是一个JSON对象,在同一个策略中我们可以定义这两个键.

这里是例子:

rabbitmqctl

rabbitmqctl set_policy ha-fed "^hf\." '{"federation-upstream-set":"all","ha-mode":"all"}' \ --priority 1 --apply-to queues
rabbitmqctl (Windows)

 

rabbitmqctl set_policy ha-fed "^hf\." "{""federation-upstream-set"":""all"", ""ha-mode"":""all""}" ^ --priority 1 --apply-to queues
HTTP API

 

PUT /api/policies/%2f/ha-fed {"pattern": "^hf\.",  "definition": {"federation-upstream-set":"all", "ha-mode": "all"},  "priority": 1,  "apply-to": "queues"}
Web UI

 

  • Navigate to Admin > Policies > Add / update a policy.
  • Enter "ha-fed" next to Name, "^hf\." next to Pattern, and select "Queues" next to Apply to.
  • Enter "federation-upstream-set" = "all" in the first line next to Policy.
  • Enter "ha-mode" = "all" on the next line.
  • Click Add policy.

这样,所有匹配"^hf\."的队列都会应用"federation-upstream-set"和"ha-mode" 定义.
.

posted on 2016-08-02 09:38 胡小军 阅读(49131) 评论(0)  编辑  收藏 所属分类: RabbitMQ

只有注册用户登录后才能发表评论。


网站导航: