3、消息协议入门:HTTP轮询与长轮询、WebSocket协议基础、AMQP协议概览、MQTT协议简介
聊消息系统,绕不开协议。我见过不少团队,上来就选 RabbitMQ 或 Kafka,结果发现业务场景根本不匹配。说白了,协议选型错了,后面怎么优化都别扭。
这一章,我带大家走一遍四种最常见的消息协议。不搞理论堆砌,重点讲清楚它们各自解决什么问题、适合什么场景。
3.1 HTTP轮询与长轮询
先说说最朴素的方案——HTTP 轮询。客户端每隔几秒发一次请求,问服务器「有消息吗?」。服务器要么返回数据,要么说「没有」。
我早期做的一个电商后台,订单状态更新就是靠轮询。前端每 3 秒调一次接口。听起来很傻对吧?但当时业务量小,开发快,确实够用。
后来有了长轮询。客户端发请求后,服务器不急着回复。它把请求「挂」在那里,等有新消息了再响应。如果超时了,客户端再重新发起。
举个例子:
// 客户端长轮询示例(伪代码)
function longPoll() {
fetch('/poll')
.then(response => response.json())
.then(data => {
// 处理消息
console.log('收到消息:', data);
// 立即发起下一次长轮询
longPoll();
})
.catch(err => {
// 出错或超时,重新连接
setTimeout(longPoll, 1000);
});
}
longPoll();
长轮询比普通轮询好一些,但本质上还是 HTTP 请求。每次都要建立连接、发送头部、解析响应。连接数一多,服务器扛不住。
我曾经维护过一个长轮询系统,高峰期 10 万连接。服务器 CPU 全耗在上下文切换上。嗯,那时候我就知道,该换协议了。
3.2 WebSocket协议基础
WebSocket 的出现,算是解决了「服务器主动推」的问题。它建立一次 TCP 连接,之后全双工通信。客户端和服务器随时可以发数据。
握手过程很简单:
// 客户端请求
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
// 服务器响应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
握手成功后,数据帧格式很轻量。头部最小只有 2 字节。对比 HTTP 请求动不动几百字节的头部,差距一目了然。
我做过一个实时协作编辑工具,用的就是 WebSocket。用户打字的同时,光标位置、文本变化实时同步。如果用轮询,体验会差很多。
但 WebSocket 也不是万能的。它需要自己处理心跳、重连、消息确认。说白了,它只提供了通道,业务逻辑得自己写。
3.3 AMQP协议概览
AMQP 全称是 Advanced Message Queuing Protocol。它和前面两种协议完全不同。AMQP 是一个线级协议,定义了消息的格式、交换方式、队列模型。
你想想看,HTTP 和 WebSocket 只是传输通道。而 AMQP 连「消息怎么路由」「怎么确认」「怎么持久化」都规定好了。
AMQP 的核心模型包含三个角色:
- Exchange(交换器):接收生产者发来的消息,根据路由键分发到队列
- Queue(队列):存储消息,等待消费者消费
- Binding(绑定):定义交换器和队列之间的路由规则
交换器有四种类型:
| 类型 | 路由规则 | 典型场景 |
|---|---|---|
| Direct | 路由键精确匹配 | 点对点消息 |
| Topic | 路由键模式匹配(支持通配符) | 发布订阅 |
| Fanout | 广播到所有绑定队列 | 日志广播 |
| Headers | 根据消息头部属性匹配 | 复杂路由 |
我习惯用 RabbitMQ 作为 AMQP 的实现。它稳定、功能全。曾经有个金融项目,要求消息不能丢、不能重复消费。AMQP 的确认机制和事务支持,正好满足需求。
3.4 MQTT协议简介
MQTT 全称是 Message Queuing Telemetry Transport。看名字就知道,它专为物联网和低带宽场景设计。
MQTT 的报文头部最小只有 2 字节。对比 HTTP 动不动几百字节,MQTT 简直是「省流量冠军」。
它的核心概念是:
- Broker(代理):消息中转服务器
- Topic(主题):消息的分类标签,支持层级结构(如
sensor/temperature/room1) - QoS(服务质量):消息送达保证级别
QoS 有三个级别:
| 级别 | 含义 | 适用场景 |
|---|---|---|
| QoS 0 | 最多一次(可能丢失) | 传感器数据,丢了无所谓 |
| QoS 1 | 至少一次(可能重复) | 控制指令,允许重复 |
| QoS 2 | 恰好一次(不丢不重) | 计费、关键事件 |
我做过一个智能家居项目,设备端用 MQTT 上报温度、湿度。设备是电池供电,网络不稳定。MQTT 的断线重连和遗嘱消息(Last Will)机制,帮了大忙。
遗嘱消息是什么?设备上线时可以注册一个遗嘱。如果设备异常断开,Broker 会自动发布这条遗嘱消息,通知其他设备「某某掉线了」。这个设计很巧妙。
下面这张图,展示了四种协议在实时性和资源消耗上的对比:
选协议没有银弹。我个人的经验是:先搞清楚你的场景要什么。要实时推送?WebSocket 或 MQTT。要可靠路由?AMQP。设备资源受限?MQTT 是首选。
嗯,这一章就到这里。协议是消息系统的基石,理解透了,后面学消息中间件会轻松很多。