知其然,知其所以然
网络协议原理 2026-10-15

Syslog:UDP 日志协议的格式与可靠性问题

实测 Syslog:PRI = 设施 × 8 + 级别(36 = auth × 8 + warning);RFC 5424 把时间戳 / 主机名 / 结构化数据放进格式;UDP 在 10% / 30% 丢包下收到 456 / 358 条(TCP 全收到);突发 20000 条时接收端丢 79.7%;日志可被轻易伪造。

网络协议 syslog UDP 日志 RFC 5424 PRI 丢包 真实验证 动画演示
网络协议原理 2026-10-15

MQTT:固定头、QoS 与保持连接

手工收发 MQTT 3.1.1 字节:CONNECT 25 字节、CONNACK 4 字节、PUBLISH 固定开销 4 字节加每次都带的主题名;剩余长度的变长编码;QoS 1 的重发会让代理收到同一个包标识两次;QoS 2 要 4 个包;保活 2 秒在 3.11 秒后触发遗嘱;保留消息让晚到的订阅者立刻拿到最新状态。

网络协议 MQTT 物联网 QoS 保活 遗嘱 保留消息 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

AMQP 模型:connection、channel、exchange、queue、binding

在 RabbitMQ 4.3.6 上用 TCP 代理解析 AMQP 0-9-1 的帧:连接握手 7 个帧,发布一条消息是方法帧加内容头加内容体 3 个帧;channel 级错误只关 channel,连接级错误关整条连接;rabbitmqctl 列出预置的 exchange、队列和绑定;100 个连接约 +1100 个 Erlang 进程,而 1 个连接 100 个 channel 只 +407。

RabbitMQ AMQP connection channel exchange queue binding 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

四种 exchange:direct、fanout、topic、headers 的路由实测

在 RabbitMQ 4.3.6 上实测四种 exchange 的路由规则:direct 逐字节相等、fanout 忽略 key、topic 的 * 与 # 匹配(含零个单词)、headers 的 x-match all/any;同队列多个绑定只收一份;1000 个绑定时 direct、topic 约 276~295 ms,headers 3387 ms。

RabbitMQ exchange direct fanout topic headers 路由 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

默认 exchange 与队列名路由

在 RabbitMQ 4.3.6 上看默认 exchange:空串名字、每个队列自动绑上 key=队列名的绑定;写错队列名消息被丢弃,mandatory + confirm 才有 UnroutableError;它不能被删、绑、重新声明(403);队列名上限 255 字节;20000 条消息走默认 exchange(中位数 545 ms)与显式 direct(536 ms)没有可测的差别。

RabbitMQ 默认exchange routing key 队列名 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

消息确认:ack、nack、reject 与 requeue

在 RabbitMQ 4.3.6 上实测消息确认:ack 前消息是 unacked 不是消失;nack requeue=True 的消息回到队首且 redelivered 变 True;nack multiple=True 一次丢一批;delivery tag 是每个 channel 自己的,跨 channel 确认得 406;auto_ack 的消息随消费者丢失;requeue 的毒消息 1 秒被投递 11967 次。

RabbitMQ ack nack reject requeue redelivered 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

发布确认:publisher confirms 的批量与单条

在 RabbitMQ 4.3.6 上用 TCP 代理看发布确认:同步发布一条一个 Ack;异步发 5000 条 broker 合并成 619 个 Ack(603 个 multiple=True);每条同步等 5752 条/秒、在途上限 100 时 54057 条/秒;不可路由的消息也会被 Ack,mandatory 会先收到 Basic.Return;reject-publish 满队列时收到 Basic.Nack。

RabbitMQ publisher confirms Basic.Ack multiple mandatory 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

mandatory 与 return:消息不可路由时去哪了

在 RabbitMQ 4.3.6 上实测 mandatory:路由不到的消息会以 312 NO_ROUTE 连同属性和消息体原样退回,Return 是异步的;direct、fanout、topic、headers 的不匹配都算不可路由,exchange 不存在则是 channel 错误;备用交换机能接住时不触发 Return;可路由时 mandatory 开销不可测。

RabbitMQ mandatory Basic.Return alternate-exchange NO_ROUTE 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

持久化:durable 队列、persistent 消息与 fsync

在 RabbitMQ 4.3.6 上实测持久化:默认拒绝非持久非排他队列(541);队列 durable 与消息 persistent 要同时满足重启后才保留;kill -9 时没等 confirm 的 5000 条只剩 4080 条,等了 confirm 的 5000 条全在;persistent 与 transient 消息写盘量几乎一样;非持久 exchange 在 4.3.6 里重启后仍在。

RabbitMQ 持久化 durable persistent delivery_mode kill -9 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

prefetch:预取数量对吞吐和公平性的影响

在 RabbitMQ 4.3.6 上实测 prefetch:它限制的是已投递未确认的条数;global_qos 在 4.3.6 默认被当成每消费者限制;自动确认不受限;loopback 上 prefetch=1 是 9718 条/秒、10 是 29665 条/秒;往返 10 ms 时 prefetch=1 只有 78 条/秒、1000 是 13488 条/秒;prefetch=1000 的消费者崩溃会让 1000 条重投。

RabbitMQ prefetch basic.qos 吞吐 背压 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

公平分发与轮询分发

在 RabbitMQ 4.3.6 上实测消息分发:相同速度的消费者轮流拿;一快一慢时 prefetch=0 要 9.37 s 而 prefetch=1 只要 1.83 s;卡住的消费者扣住的消息数等于 prefetch;x-priority 让高优先级的消费者先拿,满了才溢出;相同消费者 1/2/4/8 个耗时按 1/N 缩短。

RabbitMQ 公平分发 轮询 prefetch x-priority 消费者 真实验证 动画演示
RabbitMQ 内部原理 2026-10-13

死信队列:TTL、拒绝与队列长度触发

在 RabbitMQ 4.3.6 上实测死信:reject / TTL 过期 / 队列超长三种原因的 x-death 头(count、reason、queue、exchange、routing-keys)和 x-first/last-death;x-dead-letter-routing-key 的影响;DLX 配错消息静默消失;用 wait 队列 + TTL 实现重试并用 count 计数;全是 expired 的死信环会被检测并丢弃。

RabbitMQ 死信队列 DLX x-death TTL maxlen 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号