AMQP协议

Advanced Message Queuing Protocol

定义

AMQP(Advanced Message Queuing Protocol)是OASIS标准的应用层消息协议,支持消息队列、灵活路由、可靠投递与事务。RabbitMQ、Azure Service Bus等企业级消息中间件采用AMQP。相比MQTT的轻量发布/订阅模型,AMQP更面向企业、功能更丰富,支持Exchange、Queue、Binding等抽象,适合复杂业务场景与高可靠消息处理。

核心特性

  • 可靠投递:支持at-least-once、exactly-once,消息持久化、确认机制(ACK)保障不丢失
  • 事务支持:支持事务边界,多消息原子提交或回滚
  • 灵活路由:Direct、Fanout、Topic、Headers等Exchange类型,实现发布/订阅、点对点、主题路由
  • 多语言与互操作:标准化协议,不同厂商实现可互通

与MQTT的选型

MQTT适合物联网设备端(资源受限、弱网)、轻量发布/订阅;AMQP适合服务端、消息中间件、工业物联网数据处理流水线。两者可互补:设备经MQTT上报至平台,平台经AMQP转发至后端系统。AMQP over TLS保障传输安全。

典型应用场景

微服务解耦、异步通信、物联网数据处理、金融交易、日志聚合等。达希物联云平台支持AMQP对接,可将设备数据转发至客户RabbitMQ、Kafka等消息系统。

达希物联云平台支持AMQP等消息协议,可对接企业消息中间件,实现物联网设备数据的可靠转发与异步处理。对于需要高可靠消息投递的工业物联网、车联网等场景,达希物联可提供基于AMQP的定制化连接方案。

交换器类型决定一条消息能进哪些队列

AMQP先把消息交给交换器,再按绑定规则推进队列,生产者通常不直接写队列。直连交换器用完整路由键匹配,扇出交换器忽略路由键把消息复制到所有绑定队列,主题交换器按点分层次做通配,头交换器则比较消息头里的键值。选错类型时,消息并不会报“协议错误”,而是静默进了错误队列,或一个消费者都匹配不到。上线前要用一条样本消息核对:路由键、绑定模式、目标队列三者是否同一套规则。

持久化要同时打在交换器、队列和消息上。只把队列声明成持久,消息仍是瞬时的,代理重启后队列还在、消息没了。物联网上报若要求断电不丢,消息投递模式必须标成持久,并且代理把消息写到磁盘之后才回确认。内存型队列只适合可以重采的遥测。

确认模式不能和事务边界混成一件事

消费者确认表示“我已经处理完,可以删除”。自动确认在消息一交出就删除,消费者崩溃会丢消息。手动确认应当放在业务写库成功之后;处理到一半就确认,等于告诉代理可以丢弃尚未落地的数据。否定确认可以选择重新入队或丢弃。反复否定又不延迟,会把同一条坏消息打满CPU,应当送进死信队列,而不是无限重投。

事务让一组发布要么全部提交要么全部撤回,代价是每条消息都要等待事务结束,吞吐明显下降。发布确认则是异步的,代理把消息落盘后批量回执。需要原子性的对账消息才用事务;设备流水线更适合发布确认加持久化。把两种机制叠在同一通道上,超时后很难分辨是事务没提交,还是确认还没回来。

预取窗口过大会先打满消费者内存

预取数量限制代理一次推给某个消费者的未确认消息条数。设得太大,慢消费者会把消息堆在本地内存,代理以为已经交付,其他空闲消费者却挨饿。设得太小,快消费者频繁等下一批,吞吐上不去。判断依据是处理一条消息的耗时:解析完就转发的,预取可以放宽;要写外部系统的,预取应接近并发处理能力,而不是通道能扛的最大值。

达希物联云平台若把设备数据转到企业的AMQP代理,蜂窝侧只保证设备到平台的到达,进交换器之后的路由、确认和预取由消息总线自己负责。平台侧看到上报成功、业务库没有记录时,应查绑定键和消费者确认,而不是先怀疑物联网卡掉线。通道心跳超时会拆掉整个连接,上面所有未确认消息都要重投,心跳应大于业务处理的最长阻塞。

进了死信队列的消息不能算业务已经成功

消息被拒绝、过期或队列长度达到上限时,可以转进死信交换器。死信只说明原队列不再处理它,不说明业务已经执行。若把死信消费者写成“补记一条成功”,现场会出现阀门没动、账上却显示下发完成。死信消息应保留原来的路由键、拒绝原因和首次入队时间,由人工或单独的补偿程序决定重放还是丢弃。没有原因字段的死信,事后无法区分是过期、拒绝还是队列满。

重放时必须使用业务序号去重,因为原消息可能已经部分执行。把死信原样再投进同一队列,而消费者仍会拒绝,会形成循环。达希物联平台把数据交到企业代理之后,成功与否要看代理的确认和死信数量,不能只看平台发出的字节。死信在整点堆积、确认数不变,应先停重放、查消费者,而不是加大物联网卡的上报频率,否则只是更快地填满死信。


相关链接

返回通信类知识库