第1章 天降奇兵
依据Manning原版与电子工业出版社中文版完整目录:从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线
第1章 天降奇兵
本课程对应Alvaro Videla、Jason J. W. Williams著《RabbitMQ实战:高效部署分布式消息队列》,汪佳南译,电子工业出版社2015年10月出版,332页,ISBN 9787121271649;原版RabbitMQ in Action由Manning于2012年4月出版。官方第8章样章明确以RabbitMQ 2.7.0为当时最新版本,本课程据此固定版本边界。
全书正式分母为12章和附录A、B、C,不把后来出现的quorum queue、stream queue、现代federation、Kubernetes operator或新CLI倒灌进原书。本页逐项覆盖10个目录节点,最终交付消息系统比较、AMQP定位、RabbitMQ 2.7安装记录、首次启动日志与版本边界表。
学习目标
- 能解释“第1章 天降奇兵”的10个目录节点,并绘制connection、channel、exchange、binding、queue与consumer边界。
- 能比较正常、压力、断线、节点故障和客户端重启轨迹,判断confirm、ack、持久化与业务完成点。
- 能设计并复现消息系统比较、AMQP定位、RabbitMQ 2.7安装记录、首次启动日志与版本边界表,用吞吐、分位延迟、ready/unacked、日志和消息ID对账支持结论。
- 能分析“按当代RabbitMQ安装文档解释2012年命令和插件布局,或把运行进程当作端到端消息验证”为何失败,并写出停止、恢复、回退与责任交接条件。
从一条AMQP消息的旅程开始
先预测:生产者打开connection和channel后声明哪些交换器、队列与绑定,basic.publish如何按exchange type和routing key选择队列,broker何时发送publisher confirm,消费者何时收到delivery并basic.ack。随后预测连接中断、队列主节点故障或消费者处理一半崩溃时,消息处于ready、unacked、已重投还是未知状态。观察前必须留下预测。
RabbitMQ 2.7的可靠性不是单开关。durable控制交换器与队列定义是否跨broker重启,delivery_mode控制消息是否请求持久化,publisher confirm描述发布到broker的确认,consumer ack描述处理后的确认,经典镜像队列描述队列副本。五者边界必须分别验证。
核心词汇与版本边界
↡消息通信是“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”中的第1个RabbitMQ 2.7概念,定义必须同时给出AMQP状态、故障边界和可观测证据、↡AMQP是“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”中的第2个RabbitMQ 2.7概念,定义必须同时给出AMQP状态、故障边界和可观测证据、↡RabbitMQ 2.7是“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”中的第3个RabbitMQ 2.7概念,定义必须同时给出AMQP状态、故障边界和可观测证据、↡Erlang是“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”中的第4个RabbitMQ 2.7概念,定义必须同时给出AMQP状态、故障边界和可观测证据、↡节点是“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”中的第5个RabbitMQ 2.7概念,定义必须同时给出AMQP状态、故障边界和可观测证据 构成本页词汇。每个词都要回答:由谁声明,属于哪个vhost,在哪个channel发生,改变什么broker或客户端状态,断线与重试后会留下什么,以及RabbitMQ 2.7之后哪些变化不属于本书。
原书目录逐节点重构
住在别人的地下城堡
目录节点 1/10。 “住在别人的地下城堡”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“本章输入与版本契约”进入“住在别人的地下城堡”,再到“救世主AMQP”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
救世主AMQP
目录节点 2/10。 “救世主AMQP”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“住在别人的地下城堡”进入“救世主AMQP”,再到“RabbitMQ简史”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
RabbitMQ简史
目录节点 3/10。 “RabbitMQ简史”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“救世主AMQP”进入“RabbitMQ简史”,再到“百里挑一”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
百里挑一
目录节点 4/10。 “百里挑一”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“RabbitMQ简史”进入“百里挑一”,再到“在UNIX系统上安装RabbitMQ”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
在UNIX系统上安装RabbitMQ
目录节点 5/10。 “在UNIX系统上安装RabbitMQ”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“百里挑一”进入“在UNIX系统上安装RabbitMQ”,再到“为什么环境很重要——生活在Erlang的世界里”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
为什么环境很重要——生活在Erlang的世界里
目录节点 6/10。 “为什么环境很重要——生活在Erlang的世界里”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“在UNIX系统上安装RabbitMQ”进入“为什么环境很重要——生活在Erlang的世界里”,再到“获取安装包”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
获取安装包
目录节点 7/10。 “获取安装包”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“为什么环境很重要——生活在Erlang的世界里”进入“获取安装包”,再到“设置文件夹结构”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
设置文件夹结构
目录节点 8/10。 “设置文件夹结构”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“获取安装包”进入“设置文件夹结构”,再到“首次运行Rabbit”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
首次运行Rabbit
目录节点 9/10。 “首次运行Rabbit”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“设置文件夹结构”进入“首次运行Rabbit”,再到“总结”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
总结
目录节点 10/10。 “总结”服务于“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”。先确定它作用于connection、channel、exchange、binding、queue、consumer、cluster node还是插件,再标出声明、路由、确认、持久化与释放边界。结论必须能从配置、rabbitmqctl或Management状态、日志、消息ID和客户端事件中复核。
机制轨迹从“首次运行Rabbit”进入“总结”,再到“本章输出与消息对账”。逐步记录AMQP方法、broker状态和客户端回调,区分“方法已发送”“broker已接收或确认”“消费者已处理”“业务结果已对账”。连接关闭、节点故障、重试和应用重启必须有独立分支,不能只画正常箭头。
实验固定RabbitMQ 2.7环境、vhost、交换器、队列、路由键和消息ID,只改变持久化、confirm、ack、消费者速度、节点或网络故障之一。比较吞吐、P95/P99、ready/unacked、内存、Erlang进程与最终消息集合,用“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”验收。
机制模型:拓扑、路由与确认
connection承担TCP与认证,channel在一条连接上复用AMQP会话;channel级协议错误可能关闭channel而不是整个节点。交换器不存储消息,它依据direct、fanout、topic或headers规则把发布路由到绑定队列;无匹配路由的消息是否可感知取决于mandatory等机制,不能默认为已入队。
队列保存ready消息并跟踪已投递未确认消息。消费者确认意味着客户端声明处理完成,断线前未确认消息通常会重新排队,因此业务处理必须能识别重复。prefetch约束未确认在途量,过大可能造成单消费者囤积,过小可能限制吞吐;实验要同时看吞吐、尾延迟与公平性。
持久化与复制需要分别证明。消息写入持久队列并标记persistent,仍不等于每次确认都完成磁盘同步;publisher confirm提供broker侧可观察边界。RabbitMQ 2.7经典镜像队列与当代quorum queue不同,本页只讨论原书策略和当时故障语义。
独立证据与生产交接
目录证据保存Manning 12章3附录与中文版节点映射;环境证据保存Erlang、RabbitMQ 2.7、客户端、节点名、cookie、vhost和插件;拓扑证据保存交换器、绑定、队列属性、消费者与经典镜像策略;运行证据保存消息生成规则、吞吐、分位延迟、ready/unacked、内存和Erlang进程。
性能判断固定消息大小、路由键分布、交换器类型、绑定数量、持久化、confirm、ack与副本语义。关闭可靠性换来的吞吐不是等价优化。平均值会隐藏磁盘刷写、垃圾回收、消费者停顿和节点切换,必须保留P95/P99与队列积压。
恢复判断从消息集合结束。节点重启、连接恢复、队列重新可见、Shovel继续运行或插件重新加载都只是阶段;还要核对每个message_id的出现次数、业务结果和未确认状态,并确认旧节点、旧消费者或旧脚本不再错误操作。
本章回顾
重新完成“从消息系统历史、AMQP开放协议、RabbitMQ选择与UNIX安装建立RabbitMQ 2.7时代的运行基线”:固定RabbitMQ 2.7和原书目录,从AMQP拓扑推导状态与确认边界,通过基线、压力与故障实验测量,最后交付消息系统比较、AMQP定位、RabbitMQ 2.7安装记录、首次启动日志与版本边界表。只有“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”与反例都可独立重放,本页才算完成。
复习与运行验收
练习
问题 1:为什么“第1章 天降奇兵”必须覆盖10个目录节点?
问题 2:本页最小不变量是什么?
问题 3:怎样构造最小反例?
问题 4:为什么不能直接用当代RabbitMQ替代本章实验?
问题 5:如何验证性能结论?
问题 6:独立交接需要什么?
名词解释
本章出现的专业名词,用大白话再讲一遍。
- 消息通信
消息通信在本页对应RabbitMQ 2.7与AMQP 0-9-1中的具体对象、方法或状态;适用范围由“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”和故障反例共同限定。
- AMQP
AMQP在本页对应RabbitMQ 2.7与AMQP 0-9-1中的具体对象、方法或状态;适用范围由“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”和故障反例共同限定。
- RabbitMQ 2.7
RabbitMQ 2.7在本页对应RabbitMQ 2.7与AMQP 0-9-1中的具体对象、方法或状态;适用范围由“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”和故障反例共同限定。
- Erlang
Erlang在本页对应RabbitMQ 2.7与AMQP 0-9-1中的具体对象、方法或状态;适用范围由“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”和故障反例共同限定。
- 节点
节点在本页对应RabbitMQ 2.7与AMQP 0-9-1中的具体对象、方法或状态;适用范围由“Erlang、RabbitMQ 2.7、节点名、cookie、目录和监听端口可由新主机复现,协议与版本结论不越过2012年原书边界”和故障反例共同限定。