兼容性和一致性
RabbitMQ 实现了 AMQP 1.0 规范和 AMQP 0-9-1 规范,并在核心部分使用了多个AMQP 0-9-1 扩展。
为了方便起见,我们链接了 0-9-1(带扩展和不带扩展)规范。如果您想了解更多关于 AMQP 0-9-1 的信息,我们建议您阅读它们。请参阅我们的AMQP 0-9-1 概述指南、AMQP 0-9-1 参考指南以及其余的文档以获取更多信息。
已弃用的类
以下类在 0-9-1 版本中已弃用。RabbitMQ 完全不实现这些类,包括代理连接到 0-8 版本客户端时,或 .NET 客户端配置为使用 0-8 时。
- access
- dtx
- file
- stream
- test
- tunnel
另请参见下面的详细规范兼容性表。
来自 AMQP 规范 0-9-1 版本的类
下表描述了各种 AMQP 协议消息类的当前实现状态。
当前状态 | 类 | 备注 |
---|---|---|
ok | connection | |
ok | channel | |
ok | exchange | |
ok | queue | |
ok | basic | |
partial | tx | 参见关于 tx 支持的说明 |
来自 AMQP 规范 0-9-1 版本的方法
下表描述了每个类中各种 AMQP 协议方法的当前实现状态。
当前状态 | 方法 | 备注 |
---|---|---|
ok | connection.start | |
ok | connection.start-ok | |
ok | connection.secure | |
ok | connection.secure-ok | |
ok | connection.tune | |
ok | connection.tune-ok | |
ok | connection.open | |
ok | connection.open-ok | |
ok | connection.close | |
ok | connection.close-ok | |
ok | channel.open | |
ok | channel.open-ok | |
partial | channel.flow | 服务器不支持 active=false。使用 basic.qos 限制预取提供了更好的控制。 |
ok | channel.flow-ok | |
ok | channel.close | |
ok | channel.close-ok | |
ok | exchange.declare | |
ok | exchange.declare-ok | |
partial | exchange.delete | 我们已将 exchange.delete 变为一个幂等断言,即交换机必须不存在,就像 exchange.declare 断言它必须存在一样。 |
ok | exchange.delete-ok | |
ok | queue.declare | |
ok | queue.declare-ok | consumer-count 参数是所有消费者的数量,而不是仅活跃的消费者数量,如规范所规定。前者对应用程序更有用。 |
ok | queue.bind | |
ok | queue.bind-ok | |
partial | queue.unbind | 我们已将 queue.unbind 变为一个幂等断言,即绑定必须不存在,就像 queue.bind 断言它必须存在一样。 |
ok | queue.unbind-ok | |
ok | queue.purge | |
ok | queue.purge-ok | |
partial | queue.delete | 我们已将 queue.delete 变为一个幂等断言,即队列必须不存在,就像 queue.declare 断言它必须存在一样。 |
ok | queue.delete-ok | |
partial | basic.qos | 服务器支持每个消费者和每个通道的限制。global 标志的语义与规范中的不同。有关更多信息,请参见消费者预取。未实现预取大小限制。 |
ok | basic.qos-ok | |
partial | basic.consume | 未实现 no-local 参数。此参数的值将被忽略,并且不会尝试阻止消费者接收在同一连接上发布的消息。 |
ok | basic.consume-ok | |
ok | basic.cancel | |
ok | basic.cancel-ok | |
ok | basic.publish | |
ok | basic.return | |
ok | basic.deliver | |
ok | basic.get | |
ok | basic.get-ok | |
ok | basic.get-empty | |
ok | basic.ack | |
partial | basic.reject | 当 requeue=false 时,服务器会丢弃消息,当 requeue=true 时,服务器会重新排队。不会尝试阻止重新传递到同一客户端。服务器不会中断已拒绝消息的消息内容的发送,即消息始终完整传递给客户端。 |
partial | basic.recover | 不支持 requeue=false 的恢复。 |
ok | tx.select | |
ok | tx.select-ok | |
ok | tx.commit | |
ok | tx.commit-ok | |
ok | tx.rollback | |
ok | tx.rollback-ok |
来自 AMQP 规范 0-9-1 版本的规则
“参考”列包含类或域、方法、字段和规则名称(如果存在)。
当前状态 | 类型 | 参与方 | 参考 | 文本 |
---|---|---|---|---|
ok | 禁止 | delivery-tag / channel-local | 传递标签仅在接收消息的通道内有效。即,客户端禁止在一个通道上接收消息,然后在另一个通道上确认它。 | |
ok | 禁止 | delivery-tag / 非零 | 服务器禁止对传递标签使用零值。零保留供客户端使用,表示“迄今为止接收的所有消息”。 | |
确实 | 应该 | redelivered / 实现 | 服务器应该在能够时尝试发出重新传递消息的信号。重新传递未成功确认的消息时,服务器应该尽可能将其传递给原始客户端。 | |
计划 | 禁止 | redelivered / 提示 | 客户端禁止依赖 redelivered 字段,而应将其视为可能已处理消息的提示。完全健壮的客户端必须能够跟踪在非事务性和本地事务性通道上接收到的重复消息。 备注: 客户端已符合要求,因为它不依赖 redelivered 字段,我们计划在将来的版本中添加重复跟踪。 | |
ok | 必须 | 客户端 | connection / start / protocol-name | 如果服务器无法支持协议头中指定的协议,则必须响应有效的协议头,然后关闭套接字连接。 |
ok | 必须 | 客户端 | connection / start / server-support | 服务器必须提供低于或等于客户端在协议头中请求的协议版本。 |
ok | 必须 | 客户端 | connection / start / client-support | 如果客户端无法处理服务器建议的协议版本,则必须关闭套接字连接,而无需发送任何进一步的数据。 |
确实 | 应该 | 客户端 | connection / start / server-properties / required-fields | 属性应该至少包含以下字段:“host”,指定服务器主机名或地址,“product”,给出服务器产品的名称,“version”,给出服务器版本的名称,“platform”,给出操作系统的名称,“copyright”,如果适用,以及“information”,给出其他一般信息。 |
ok | 必须 | 客户端 | connection / start / locales / required-support | 服务器必须至少支持 en_US 语言环境。 |
确实 | 应该 | 服务器 | connection / start-ok / client-properties / required-fields | 属性应该至少包含以下字段:“product”,给出客户端产品的名称,“version”,给出客户端版本的名称,“platform”,给出操作系统的名称,“copyright”,如果适用,以及“information”,给出其他一般信息。 |
ok | 应该 | 服务器 | connection / start-ok / mechanism / security | 客户端应该使用它可以处理的最高级别的安全配置文件进行身份验证,该配置文件来自服务器提供的列表。 |
ok | 必须 | 服务器 | connection / start-ok / mechanism / validity | 如果 mechanism 字段不包含 Start 方法中服务器建议的安全机制之一,则服务器必须关闭连接,而无需发送任何进一步的数据。 |
ok | 必须 | 客户端 | connection / tune / frame-max / minimum | 在协商 frame-max 之前,两个对等方必须接受最大为 frame-min-size 字节的帧,并且 frame-max 的最小协商值也是 frame-min-size。 |
计划 | 必须 | 服务器 | connection / tune-ok / channel-max / upper-limit | 如果客户端指定的 channel max 高于服务器提供的值,则服务器必须关闭连接,而无需尝试协商关闭。服务器可能会以某种方式报告错误以帮助实施者。 |
ok | 必须 | 服务器 | connection / tune-ok / frame-max / minimum | 在协商 frame-max 之前,两个对等方必须接受最大为 frame-min-size 字节的帧,并且 frame-max 的最小协商值也是 frame-min-size。 备注: frame-min-size 为 4Kb。 |
ok | 必须 | 服务器 | connection / tune-ok / frame-max / upper-limit | 如果客户端指定的 frame max 高于服务器提供的值,则服务器必须关闭连接,而无需尝试协商关闭。服务器可能会以某种方式报告错误以帮助实施者。 |
ok | 必须 | 服务器 | connection / open / virtual-host / separation | 如果服务器支持多个虚拟主机,则必须对每个虚拟主机的交换机、队列和所有关联实体进行完全隔离。连接到特定虚拟主机的应用程序禁止访问另一个虚拟主机的资源。 |
确实 | 应该 | 服务器 | connection / open / virtual-host / security | 服务器应该验证客户端是否具有访问指定虚拟主机的权限。 |
ok | 必须 | 客户端 | connection / close / stability | 发送此方法后,必须丢弃除 Close 和 Close-OK 之外的任何接收到的方法。接收 Close 后发送 Close 的响应必须是发送 Close-Ok。 |
确实 | 应该 | 客户端 | connection / close-ok / reporting | 在未收到 Close-Ok 握手方法的情况下检测到套接字关闭的对等方应该记录错误。 备注: 只有服务器维护错误日志。 |
ok | 禁止 | 服务器 | channel / open / state | 客户端禁止在已打开的通道上使用此方法。 |
没有 | 可以 | 服务器 | channel / flow / initial-state | 打开新通道时,它是活动的(流处于活动状态)。某些应用程序假设通道在启动之前处于非活动状态。要模拟此行为,客户端可以在打开通道后将其暂停。 |
没有 | 应该 | 服务器 | channel / flow / bidirectional | 发送内容帧时,对等方应该监视通道是否有传入方法,并尽快响应 Channel.Flow。 备注: 服务器不支持使用 active=true 的阻塞流。使用 basic.qos 限制预取提供了更好的控制。 |
ok | 可以 | 服务器 | channel / flow / throttling | 对等方可以使用 Channel.Flow 方法出于内部原因限制传入内容数据,例如,在通过较慢的连接交换数据时。 备注: 服务器和客户端都不会自动发出 Channel.Flow。 |
没有 | 可以 | 服务器 | channel / flow / expected-behaviour | 请求 Channel.Flow 方法的节点**可以**断开连接和/或禁止不遵守请求的节点。这样做是为了防止行为不良的客户端压垮服务器。 |
ok | 必须 | 客户端 | 通道 / 关闭 / 稳定性 | 发送此方法后,必须丢弃除 Close 和 Close-OK 之外的任何接收到的方法。接收 Close 后发送 Close 的响应必须是发送 Close-Ok。 |
确实 | 应该 | 客户端 | 通道 / 关闭确认 / 报告 | 检测到套接字关闭但未收到 Channel.Close-Ok 握手方法的节点**应该**记录错误。 备注: 只有服务器维护错误日志。 |
ok | 必须 | 交换机 / 必需类型 | 服务器**必须**实现以下标准交换机类型:fanout、direct。 | |
确实 | 应该 | 交换机 / 推荐类型 | 服务器**应该**实现以下标准交换机类型:topic、headers。 | |
ok | 必须 | 交换机 / 必需实例 | 服务器**必须**在每个虚拟主机中,为其实现的每种标准交换机类型预先声明一个交换机实例,其中交换机实例的名称(如果定义)为“amq.”后跟交换机类型名称。 | |
ok | 必须 | 交换机 / 默认交换机 | 服务器**必须**预先声明一个没有公共名称的 direct 交换机,用作内容发布方法和默认队列绑定的默认交换机。 | |
ok | 禁止 | 交换机 / 默认访问 | 服务器**不得**允许客户端访问默认交换机,除非在 Queue.Bind 和内容发布方法中指定空交换机名称。 | |
确实 | 可以 | 交换机 / 扩展 | 服务器**可以**根据需要实现其他交换机类型。 | |
确实 | 应该 | 服务器 | 交换机 / 声明 / 最小值 | 服务器**应该**支持每个虚拟主机至少 16 个交换机,理想情况下,除了可用资源定义的限制外,不应施加任何限制。 |
ok | 必须,可以 | 服务器 | 交换机 / 声明 / 交换机 / 保留 | 以“amq.”开头的交换机名称保留用于预先声明的和标准化的交换机。如果设置了 passive 选项,或者交换机已经存在,则客户端**可以**声明以“amq.”开头的交换机。 注释: 服务器不会阻止以“amq.”开头的交换机名称被声明。客户端可以在没有设置 passive 位的情况下声明以“amq.”开头的交换机。 |
ok | 必须 | 服务器 | 交换机 / 声明 / 交换机 / 语法 | 交换机名称由以下字符组成的非空序列组成:字母、数字、连字符、下划线、句点或冒号。 注释: 服务器不会强制执行词法。 |
ok | 必须 | 服务器 | 交换机 / 声明 / 类型 / 类型化 | 交换机不能使用不同的类型重新声明。客户端**不得**尝试使用与原始 Exchange.Declare 方法中使用的类型不同的类型重新声明现有交换机。 |
ok | 禁止 | 服务器 | 交换机 / 声明 / 类型 / 支持 | 客户端**不得**尝试使用服务器不支持的类型声明交换机。 |
ok | 必须 | 服务器 | 交换机 / 声明 / passive / 未找到 | 如果设置了该选项,并且交换机尚不存在,则服务器**必须**引发通道异常,回复代码为 404(未找到)。 注释: (指的是 passive 标志) |
ok | 必须 | 服务器 | 交换机 / 声明 / passive / 等价 | 如果未设置且交换机存在,则服务器**必须**检查现有交换机是否具有 type、durable 和 arguments 字段的相同值。如果请求的交换机与这些字段匹配,则服务器**必须**以 Declare-Ok 响应,如果不匹配,则**必须**引发通道异常。 注释: (指的是 passive 标志) |
ok | 必须 | 服务器 | 交换机 / 声明 / durable / 支持 | 服务器**必须**支持持久和短暂的交换机。 |
失败 | 禁止 | 服务器 | 交换机 / 删除 / 交换机 / 存在 | 客户端**不得**尝试删除不存在的交换机。 注释: 我们已将 exchange.delete 变成一个幂等断言,即交换机必须不存在,就像 exchange.declare 断言它必须存在一样。 |
ok | 禁止 | 服务器 | 交换机 / 删除 / if-unused / 使用中 | 如果 if-unused 字段为 true,则服务器**不得**删除在其上具有绑定的交换机。 |
ok | 必须 | 服务器 | 队列 / 声明 / 默认绑定 | 服务器**必须**为新声明的队列创建一个到默认交换机的默认绑定,该交换机是类型为“direct”的交换机,并使用队列名称作为路由键。 |
确实 | 应该 | 服务器 | 队列 / 声明 / 最小队列数 | 服务器**应该**支持每个虚拟主机至少 256 个队列,理想情况下,除了可用资源定义的限制外,不应施加任何限制。 |
确实 | 可以,必须 | 服务器 | 队列 / 声明 / 队列 / 默认名称 | 队列名称**可以**为空,在这种情况下,服务器**必须**创建一个具有唯一生成名称的新队列,并在 Declare-Ok 方法中将其返回给客户端。 |
ok | 必须 | 服务器 | 队列 / 声明 / 队列 / 保留 | 以“amq.”开头的队列名称保留用于预先声明的和标准化的队列。如果设置了 passive 选项,或者队列已经存在,则客户端**可以**声明以“amq.”开头的队列。 注释: 服务器不会阻止以“amq.”开头的队列名称被声明。客户端可以在没有设置 passive 位的情况下声明以“amq.”开头的队列。 |
确实 | 可以 | 服务器 | 队列 / 声明 / 队列 / 语法 | 队列名称可以为空,也可以是以下字符组成的序列:字母、数字、连字符、下划线、句点或冒号。 注释: 服务器不会强制执行词法。 |
确实 | 可以 | 服务器 | 队列 / 声明 / passive / passive | 客户端**可以**要求服务器断言队列存在,而如果队列不存在则不创建队列。如果队列不存在,服务器将将其视为失败。 |
ok | 必须 | 服务器 | 队列 / 声明 / passive / 等价 | 如果未设置且队列存在,则服务器**必须**检查现有队列是否具有 durable、exclusive、auto-delete 和 arguments 字段的相同值。如果请求的队列与这些字段匹配,则服务器**必须**以 Declare-Ok 响应,如果不匹配,则**必须**引发通道异常。 注释: (指的是 passive 标志) |
ok | 必须 | 服务器 | 队列 / 声明 / durable / 持久性 | 服务器**必须**在重新启动后重新创建持久队列。 |
ok | 必须 | 服务器 | 队列 / 声明 / durable / 类型 | 服务器**必须**支持持久和短暂的队列。 |
ok | 必须 | 服务器 | 队列 / 声明 / exclusive / 类型 | 服务器**必须**支持独占(私有)和非独占(共享)队列。 |
没有 | 不可以 | 服务器 | 队列 / 声明 / exclusive / 独占 | 客户端**不得**尝试使用由另一个仍然打开的连接声明为独占的队列。 |
ok | 必须 | 服务器 | 队列 / 声明 / auto-delete / 预先存在 | 如果队列已存在,则服务器**必须**忽略 auto-delete 字段。 |
ok | 必须 | 服务器 | 队列 / 绑定 / 重复 | 服务器**必须**允许忽略重复绑定 - 也就是说,针对特定队列的两个或多个绑定方法,具有相同的参数 - 而不将其视为错误。 |
ok | 禁止 | 服务器 | 队列 / 绑定 / 唯一 | 即使队列具有多个与消息匹配的绑定,服务器**不得**将相同的消息多次传递到队列。 |
ok | 必须 | 服务器 | 队列 / 绑定 / 短暂交换机 | 服务器**必须**允许持久队列绑定到短暂交换机。 |
ok | 必须 | 服务器 | 队列 / 绑定 / 持久交换机 | 持久队列到持久交换机的绑定自动持久,服务器**必须**在服务器重启后恢复此类绑定。 |
确实 | 应该 | 服务器 | 队列 / 绑定 / 绑定计数 | 服务器**应该**支持每个队列至少 4 个绑定,理想情况下,除了可用资源定义的限制外,不应施加任何限制。 |
ok | 必须 | 服务器 | 队列 / 绑定 / 队列 / 队列已知 | 客户端**必须**指定队列名称或之前在同一通道上声明过队列 |
ok | 禁止 | 服务器 | 队列 / 绑定 / 队列 / 必须存在 | 客户端**不得**尝试绑定不存在的队列。 |
ok | 禁止 | 服务器 | 队列 / 绑定 / 交换机 / 交换机存在 | 客户端**不得**被允许将队列绑定到不存在的交换机。 |
没有 | 必须 | 服务器 | 队列 / 绑定 / 交换机 / 默认交换机 | 服务器**必须**接受空白交换机名称表示默认交换机。 |
ok | 必须 | 服务器 | 队列 / 绑定 / 路由键 / direct 交换机键匹配 | 如果消息队列使用路由键 K 绑定到 direct 交换机,并且发布者向交换机发送具有路由键 R 的消息,则如果 K = R,则**必须**将消息传递到消息队列。 |
ok | 必须 | 服务器 | 队列 / 解绑 / 01 | 如果解绑失败,服务器**必须**引发连接异常。 |
ok | 必须 | 服务器 | 队列 / 解绑 / 队列 / 队列已知 | 客户端**必须**指定队列名称或之前在同一通道上声明过队列 |
失败 | 禁止 | 服务器 | 队列 / 解绑 / 队列 / 必须存在 | 客户端**不得**尝试解绑不存在的队列。 注释: 我们已将 queue.unbind 变成一个幂等断言,即绑定必须不存在,就像 queue.bind 断言它必须存在一样。 |
失败 | 禁止 | 服务器 | 队列 / 解绑 / 交换机 / 必须存在 | 客户端**不得**尝试将队列从不存在的交换机中解绑。 注释: 我们已将 queue.unbind 变成一个幂等断言,即绑定必须不存在,就像 queue.bind 断言它必须存在一样。 |
没有 | 必须 | 服务器 | 队列 / 解绑 / 交换机 / 默认交换机 | 服务器**必须**接受空白交换机名称表示默认交换机。 |
ok | 禁止 | 服务器 | 队列 / 清除 / 02 | 服务器**不得**清除已发送到客户端但尚未确认的消息。 |
没有 | 可以 | 服务器 | 队列 / 清除 / 03 | 服务器**可以**实现一个清除队列或日志,允许系统管理员恢复意外清除的消息。服务器**不应该**将已清除的消息保存在与活动消息相同的存储空间中,因为已清除的消息量可能会变得非常大。 |
ok | 必须 | 服务器 | 队列 / 清除 / 队列 / 队列已知 | 客户端**必须**指定队列名称或之前在同一通道上声明过队列 |
ok | 禁止 | 服务器 | 队列 / 清除 / 队列 / 必须存在 | 客户端**不得**尝试清除不存在的队列。 |
没有 | 应该 | 服务器 | 队列 / 删除 / 01 | 服务器**应该**使用死信队列来保存已在已删除队列中挂起的邮件,并且**可以**为系统管理员提供将这些邮件移回活动队列的功能。 |
ok | 必须 | 服务器 | 队列 / 删除 / 队列 / 队列已知 | 客户端**必须**指定队列名称或之前在同一通道上声明过队列 |
失败 | 禁止 | 服务器 | 队列 / 删除 / 队列 / 必须存在 | 客户端**不得**尝试删除不存在的队列。 注释: 我们已将 queue.delete 变成一个幂等断言,即队列必须不存在,就像 queue.declare 断言它必须存在一样。 |
ok | 禁止 | 服务器 | 队列 / 删除 / if-unused / 使用中 | 如果 if-unused 字段为 true,则服务器**不得**删除在其上具有消费者的队列。 |
ok | 禁止 | 服务器 | 队列 / 删除 / if-empty / 不为空 | 如果 if-empty 字段为 true,则服务器**不得**删除在其上具有消息的队列。 |
确实 | 应该 | 基本 / 01 | 服务器**应该**尊重基本消息的持久属性,并且**应该**尽最大努力将持久基本消息保存在可靠的存储机制上。 | |
ok | 禁止 | 基本 / 02 | 服务器**不得**在队列溢出的情况下丢弃持久基本消息。 | |
没有 | 可以 | 基本 / 03 | 服务器**可以**使用 Channel.Flow 方法在必要时减慢或停止基本消息发布者。 | |
确实 | 可以 | 基本 / 04 | 服务器**可以**将非持久基本消息溢出到持久存储。 | |
没有 | 可以 | 基本 / 05 | 如果队列大小超过某个配置的限制,则服务器**可以**优先丢弃或将非持久基本消息放入死信队列。 | |
计划 | 必须 | 基本 / 06 | 服务器**必须**为基本消息实现至少 2 个优先级,其中优先级 0-4 和 5-9 被视为两个不同的级别。 | |
没有 | 可以 | 基本 / 07 | 服务器**可以**实现最多 10 个优先级。 | |
ok | 必须 | 基本 / 08 | 服务器**必须**按顺序传递相同优先级的消息,而不管其各自的持久性如何。 | |
ok | 必须 | 基本 / 09 | 服务器**必须**支持 Basic 内容的未确认传递,即 no-ack 字段设置为 TRUE 的消费者。 | |
ok | 必须 | 基本 / 10 | 服务器**必须**支持对基本内容进行显式确认的投递,即对于将no-ack字段设置为FALSE的消费者。 | |
ok | 必须 | 服务器 | basic / qos / prefetch-size / 01 | 当客户端没有处理任何消息时,服务器**必须**忽略此设置——即prefetch-size不限制向客户端传输单个消息,只限制在客户端仍有1条或多条未确认的消息时预先发送更多消息。 注释: (指的是prefetch-size) |
ok | 禁止 | 服务器 | basic / qos / prefetch-count / 01 | 服务器可以预先发送比客户端指定的prefetch窗口允许的更少的数据,但**不能**发送更多。 |
确实 | 应该 | 服务器 | basic / consume / 01 | 服务器**应该**支持每个队列至少16个消费者,理想情况下,除了可用资源定义的限制外,不应施加任何限制。 |
ok | 禁止 | 服务器 | basic / consume / consumer-tag / 01 | 客户端**不能**指定引用现有消费者的标签。 |
ok | 必须 | 服务器 | basic / consume / consumer-tag / 02 | 消费者标签仅在创建消费者的通道内有效。即,客户端**不能**在一个通道中创建消费者,然后在另一个通道中使用它。 |
没有 | 不可以 | 服务器 | basic / consume / exclusive / 01 | 客户端**可能无法**获得对已存在活动消费者的队列的独占访问权。 |
ok | 必须 | 服务器 | basic / cancel / 01 | 如果队列不存在,服务器**必须**忽略cancel方法,只要消费者标签对该通道有效。 |
ok | 禁止 | 服务器 | basic / publish / exchange / must-exist | 客户端**不能**尝试将内容发布到不存在的交换机。 |
ok | 必须 | 服务器 | basic / publish / exchange / default-exchange | 服务器**必须**接受空白交换机名称表示默认交换机。 |
ok | 必须 | 服务器 | basic / publish / exchange / 02 | 如果交换机声明为内部交换机,则服务器**必须**引发带有回复代码403(拒绝访问)的通道异常。 |
没有 | 可以 | 服务器 | basic / publish / exchange / 03 | 交换机**可能**拒绝基本内容,在这种情况下,它**必须**引发带有回复代码540(未实现)的通道异常。 |
确实 | 应该 | 服务器 | basic / publish / mandatory / 01 | 服务器**应该**实现mandatory标志。 |
没有 | 应该 | 服务器 | basic / publish / immediate / 01 | 服务器**应该**实现immediate标志。 注释: 服务器不支持immediate标志。消息TTL为0提供了一种替代方案。 |
计划 | 应该 | 客户端 | basic / deliver / 01 | 服务器**应该**跟踪消息已投递到客户端的次数,以及当消息在一定次数(例如5次)内未被确认而被重新投递时,服务器**应该**将消息视为不可处理(可能导致客户端应用程序中止),并将消息移动到死信队列。 |
ok | 必须 | 服务器 | basic / ack / multiple / exists | 服务器**必须**验证非零delivery-tag是否引用已投递的消息,如果不是,则引发通道异常。在事务性通道上,此检查**必须**立即完成,而不是延迟到Tx.Commit。具体来说,客户端**不能**多次确认同一消息。 |
计划 | 应该 | 服务器 | basic / reject / 01 | 服务器**应该**能够在使用Deliver或Get-Ok方法发送消息内容时接受和处理Reject方法。即,服务器应该在发送输出帧的同时读取和处理传入的方法。要取消部分发送的内容,服务器发送大小为1的内容体帧(即,除了帧结束八位字节外没有数据)。 |
ok | 应该 | 服务器 | basic / reject / 02 | 服务器**应该**将此方法解释为客户端目前无法处理消息。 |
ok | 禁止 | 服务器 | basic / reject / 03 | 客户端**不能**使用此方法作为选择要处理的消息的方法。 |
计划 | 禁止 | 服务器 | basic / reject / requeue / 01 | 服务器**不能**在当前通道的上下文中将消息投递到同一客户端。建议的策略是尝试将消息投递到备用消费者,如果这不可行,则将消息移动到死信队列。服务器**可以**使用更复杂的跟踪来保留队列上的消息,并在稍后阶段将其重新投递到同一客户端。 |
ok | 必须 | 服务器 | basic / recover-async / 01 | 服务器**必须**在所有重新发送的消息上设置redelivered标志。 |
ok | 必须 | 服务器 | basic / recover / 01 | 服务器**必须**在所有重新发送的消息上设置redelivered标志。 |
ok | 禁止 | tx / not multiple queues | 应用程序**不能**依赖影响多个队列的事务的原子性。 | |
ok | 禁止 | tx / not immediate | 应用程序**不能**依赖包含使用immediate选项发布的消息的事务的行为。 | |
ok | 禁止 | tx / not mandatory | 应用程序**不能**依赖包含使用mandatory选项发布的消息的事务的行为。 | |
ok | 禁止 | 服务器 | tx / commit / transacted | 客户端**不能**在非事务性通道上使用Commit方法。 |
ok | 禁止 | 服务器 | tx / rollback / transacted | 客户端**不能**在非事务性通道上使用Rollback方法。 |
来自AMQP规范版本0-9-1(PDF)的规则
下面列出的规则来自0-9-1规范的PDF版本,在文本中出现MUST、SHOULD或MAY时。
当前状态 | 类型 | 参与方 | 参考 | 文本 |
---|---|---|---|---|
does,doesn't | SHOULD,SHOULD | 1.4.1 | 协议常量显示为大写名称。AMQP实现**应该**在源代码和文档中定义和使用常量时使用这些名称。属性名称、方法参数和帧字段显示为小写名称。AMQP实现**应该**在源代码和文档中一致地使用这些名称。 注释: 属性名称、方法参数和帧字段在某些上下文中合法地显示为驼峰命名法。 | |
ok | 必须 | 2.2.4 | 对于未完全打开的连接,没有错误的握手。在成功协商协议头之后,[...] 以及在发送或接收Open或Open-Ok之前,检测到错误的对等方**必须**关闭套接字,而无需发送任何其他数据。 | |
确实 | 可以 | 2.3.3 | 服务器**可以**在同一端口上托管多个协议。 注释: 服务器在同一端口上支持0-8、0-9和0-9-1。 | |
没有 | 可以 | 2.3.3 | 商定的限制**可以**使双方预先分配关键缓冲区,避免死锁。 | |
ok | 必须 | 2.3.3 | 每个传入帧要么遵守商定的限制,因此是“安全的”,要么超过它们,在这种情况下,另一方**有故障**,**必须**断开连接。 | |
ok | 必须 | 2.3.3 | 服务器**必须**告诉客户端它提出的限制。 | |
没有 | 可以 | 2.3.3 | 客户端做出响应,并**可以**减少其连接的这些限制。 | |
确实 | 可以 | 2.3.5.2 | 数据[对于内容帧]可以是任何大小,并且**可以**分成几个(或许多)块,每个块形成一个“内容体帧”。 | |
ok | MUST,MUST | 2.3.7 | 当客户端发送Open时,连接或通道被视为对客户端“打开”,当服务器发送Open-Ok时,连接或通道被视为对服务器“打开”。从这一点开始,希望关闭通道或连接的对等方**必须**使用握手协议[...]来执行此操作。当对等方决定关闭通道或连接时,它发送Close方法。接收对等方**必须**以Close-Ok响应Close,然后双方都可以关闭其通道或连接。 | |
确实 | MUST NOT,MUST NOT | 3.1.1 | 服务器**不能**修改它接收并传递给消费者应用程序的消息内容体。[...] [服务器]**不能**删除或修改现有信息。 注释: 路由后,将从属性中删除“BCC”头。 | |
没有 | 可以 | 3.1.1 | 服务器**可以**向内容头添加信息[...] | |
ok | 必须 | 3.1.2 | 每个连接**必须**与单个虚拟主机关联。 | |
没有 | 可以 | 3.1.2 | [所使用的]授权方案**可以**对每个虚拟主机都是唯一的。 | |
ok | MUST,MUST | 3.1.3.1 | 服务器**必须**实现direct交换机类型,并且**必须**在每个虚拟主机内预先声明至少两个direct交换机:一个名为amq.direct,另一个没有公共名称,用作Publish方法的默认交换机。[...] [所有]消息队列**必须**使用消息队列的名称作为路由键自动绑定到无名交换机。 | |
ok | 必须 | 3.1.3.3 | 用于topic交换机的路由键**必须**由零个或多个以点分隔的单词组成。 | |
does,ok | SHOULD,MUST | 3.1.3.3 | 服务器**应该**实现topic交换机类型,在这种情况下,服务器**必须**在每个虚拟主机内预先声明至少一个名为amq.topic的topic交换机。 | |
does,ok | SHOULD,MUST | 3.1.3.4 | 服务器**应该**实现headers交换机类型,在这种情况下,服务器**必须**在每个虚拟主机内预先声明至少一个名为amq.match的headers交换机。 | |
ok | 必须 | 3.1.3.4 | 所有非规范交换机类型**必须**以“x-”开头命名。 | |
确实 | 不可以 | 3.1.4 | 请注意,在存在来自队列的多个读取器、客户端事务、优先级字段的使用、消息选择器的使用或特定于实现的投递优化的情况下,队列**可能**不会表现出真正的FIFO特性。 注释: 在第4.7节中指定的条件下保证FIFO特性。 | |
ok | 必须 | 3.1.10 | 服务器和客户端**必须**遵守[指定的命名]约定 | |
确实 | 应该 | 3.2.1 | AMQP方法可能出于互操作性原因定义特定的最小值(例如每个消息队列的消费者数量)。这些最小值在每个类的描述中定义。符合AMQP的实现**应该**为这些字段实现合理宽松的值,最小值仅用于功能最弱的平台。 | |
does,doesn't | SHOULD,MAY | 3.2.1 | 发送对等方**应该**等待特定回复方法[在发送同步请求后],但**可以**异步实现此方法 | |
ok | 必须 | 4.2.2 | 客户端**必须**通过发送协议头来启动新连接。 | |
没有 | 可以 | 4.2.2 | 服务器**可以**接受非AMQP协议,例如HTTP。 注释: 核心代理仅接受AMQP。插件存在于其他协议中。 | |
ok | 必须 | 4.2.2 | 如果服务器无法识别套接字上数据的头5个八位字节,或者不支持客户端请求的特定协议版本,它**必须**将有效的协议头写入套接字,然后刷新套接字(以确保客户端应用程序将接收数据),然后关闭套接字连接。 | |
确实 | 可以 | 4.2.2 | 服务器**可以**打印诊断消息[在协议协商失败期间]以帮助调试。 注释: 相关信息将写入服务器日志。 | |
没有 | 可以 | 4.2.2 | 客户端**可以**通过尝试使用其支持的最高版本连接并在从服务器接收此类信息时使用较低版本重新连接来检测服务器协议版本。 | |
ok | 必须 | 4.2.3 | 帧结束八位字节**必须**始终是十六进制值%xCE。 | |
ok | MUST,MUST,MUST | 4.2.3 | 如果对等方收到一个类型不是这些定义类型之一的帧,它**必须**将其视为致命协议错误,并关闭连接,而无需在其上发送任何其他数据。当对等方读取帧时,它**必须**在尝试解码帧之前检查帧结束是否有效。如果帧结束无效,它**必须**将其视为致命协议错误,并关闭连接,而无需在其上发送任何其他数据。 | |
确实 | 应该 | 4.2.3 | 它**应该**记录有关[帧解码]问题的信息,因为这表示服务器或客户端帧代码实现中的错误。 | |
ok | MUST NOT,MUST,MUST,MUST,MUST | 4.2.3 | 对等方**不得**发送大于约定大小的帧。收到过大帧的对等方**必须**以回复代码 501(帧错误)发出连接异常信号。所有心跳帧以及引用 Connection 类的 method、header 和 body 帧的信道号**必须**为零。收到这些帧之一的非零信道号的对等方**必须**以回复代码 503(命令无效)发出连接异常信号。 | |
ok | 禁止 | 4.2.5.1 | 实现者**不得**假设帧中编码的整数在内存字边界上对齐。 | |
ok | 必须 | 4.2.5.5 | 字段名称**必须**以字母、“$”或“#”开头 [...] | |
不,不 | SHOULD,SHOULD | 4.2.5.5 | 服务器**应该**验证字段名称,并在收到无效字段名称时,**应该**以回复代码 503(语法错误)发出连接异常信号。 | |
计划 | 必须 | 4.2.6 | 收到不完整或格式错误内容的对等方**必须**以回复代码 505(意外帧)引发连接异常。 注意: 对于内容可能出现格式错误的所有可能方式,都不会返回给定的回复代码。 | |
ok | MUST,MUST | 4.2.6.1 | 类 ID [内容头] **必须**与方法帧类 ID 匹配。对等方**必须**通过以回复代码 501(帧错误)引发连接异常来响应无效的类 ID。 | |
ok | 不得,必须 | 4.2.6.1 | 内容帧中的信道号**不得**为零。收到内容帧中信道号为零的对等方**必须**以回复代码 504(信道错误)发出连接异常信号。 | |
ok | 必须 | 4.2.6.2 | 对等方**必须**处理拆分为多个帧的内容主体,方法是将这些帧存储为单个集合,并按原样重新传输它们、将其拆分为更小的帧或将其连接成单个块以交付给应用程序。 | |
ok | 必须 | 4.2.6.2 | 心跳帧的信道号**必须**为零。 | |
ok | 必须 | 4.2.7 | 如果对等方不支持心跳,则**必须**丢弃心跳帧,而无需发出任何错误或故障信号。 注意: 代理和支持的客户端确实支持心跳帧。 | |
does,doesn't | 可以,可以 | 4.3 | AMQP 对等方**可以**支持多个信道。最大信道数在连接协商中定义,对等方**可以**将此协商降低到 1。 | |
does,doesn't | 应该,不应该 | 4.3 | 每个对等方**应该**以公平的方式平衡所有打开信道上的流量。此平衡可以在每个帧的基础上进行,也可以在每个信道流量量基础上进行。对等方**不应该**允许一个非常繁忙的信道饿死较不繁忙的信道的进度。 | |
ok | 不得,必须 | 4.6 | 请求-响应的效果**不得**在响应方法之前在信道上可见,并且此后**必须**可见。 | |
ok | 必须 | 4.7 | 服务器**必须**保留通过单个内容处理路径流动的内容顺序,除非在 Basic.Deliver 或 Basic.Get-Ok 方法上设置了 redelivered 字段,并根据管理该字段可以设置的条件的规则。 注意: 代理提供了更强的保证。 | |
确实 | 应该 | 4.10.2 | 服务器**应该**记录所有[连接协商阶段期间的异常],并标记或阻止引发多次故障的客户端。 |
来自 AMQP 规范版本 0-8 的规则
下面列出的规则与 RabbitMQ 支持但已弃用的功能相关。
当前状态 | 类型 | 参与方 | 参考 | 文本 |
---|---|---|---|---|
没有 | 应该 | 客户端 | method/connection/redirect:获取 Connection.Redirect 方法时,客户端**应该**重新连接到指定的宿主机,如果该宿主机不存在,则重新连接到已知主机列表中指定的任何宿主机。 | |
没有 | 应该 | 客户端 | method/connection/redirect:获取 Connection.Redirect 方法时,客户端**应该**重新连接到指定的宿主机,如果该宿主机不存在,则重新连接到已知主机列表中指定的任何宿主机。 | |
确实 | 可以 | 服务器 | domain/known hosts:如果服务器只知道自身以外的其他宿主机,则**可以**将此字段留空。 |
获取帮助和提供反馈
如果您对本指南的内容或与 RabbitMQ 相关的任何其他主题有任何疑问,请随时使用GitHub Discussions或我们的社区Discord 服务器提出。
帮助我们改进文档 <3
如果您想为网站做出改进,其源代码可在GitHub 上获取。只需分叉存储库并提交拉取请求即可。谢谢!