MQTT 是什么?它的核心特点和工作原理是什么?
MQTT 是一种基于 TCP 的轻量级消息协议,最常见于物联网设备、移动推送和实时状态同步。它的核心不是“像 HTTP 一样请求接口”,而是通过 Broker 做发布/订阅:设备把消息发布到主题,其他客户端订阅主题后由 Broker 推送消息。这个模式让设备不必知道彼此地址,也能在弱网、低带宽和大量连接场景下稳定通信。
MQTT 为什么适合物联网?
第一个特点是轻量。MQTT 固定头部最小只有 2 字节,比 HTTP 一大串 header 更省流量。对电池供电设备来说,少发一点数据、少建立几次连接,都会影响续航。它还通过 Keep Alive 维持长连接,Broker 可以主动把消息推给客户端,不需要客户端频繁轮询。
第二个特点是发布/订阅。发布者只把消息发到 topic,例如 factory/line1/motor/temperature,订阅者通过主题过滤器接收自己关心的消息。Broker 负责连接管理、主题匹配、消息分发和 QoS 状态。这个设计天然支持一对多,比如一台设备上报状态后,监控系统、告警系统和数据存储服务都可以同时收到。
第三个特点是可靠性交给 QoS 分级处理。QoS 0 最快但可能丢,QoS 1 保证至少到达但可能重复,QoS 2 尽量做到恰好一次但成本最高。实际项目里通常不是全部用最高级别,而是遥测用 QoS 0,告警和状态变更用 QoS 1,极少数关键命令才考虑 QoS 2。
MQTT 的工作流程可以概括为四步:客户端 CONNECT 到 Broker,订阅者 SUBSCRIBE 主题,发布者 PUBLISH 消息,Broker 根据订阅关系转发。断线时,Broker 可以通过遗嘱消息通知其他系统;重连时,持久会话可以恢复订阅和未确认消息。它看起来简单,但真正上线时要同时考虑主题设计、认证授权、离线消息上限和消息幂等。
它也不是所有实时通信的默认答案。浏览器前端更常用 WebSocket,服务端内部任务分发可能更适合 Kafka 或 RabbitMQ,MQTT 的强项是大量客户端长连接和主题路由。判断是否使用 MQTT,可以先问三个问题:设备是否经常在线保持连接、消息是否需要按主题推送、网络和功耗是否敏感。如果答案都是否定,HTTP 可能更简单。
bashmosquitto_sub -h test.mosquitto.org -t 'levenx/demo' mosquitto_pub -h test.mosquitto.org -t 'levenx/demo' -m 'hello mqtt'
初学者可以用公开测试 Broker 验证协议概念,但不要把它当作生产样板。生产 Broker 要考虑账号隔离、TLS 证书、ACL、限流、日志和监控,还要有备份和升级方案。MQTT 的入门门槛低,真正难的是长期稳定运行。越早把这些工程约束放进设计,后面越少返工。
追问
MQTT 和 HTTP 最大区别是什么?
HTTP 主要是请求/响应,客户端问一次,服务器答一次。MQTT 是长连接加发布/订阅,Broker 可以在有消息时主动推给订阅者。取舍很明显:配置查询、文件上传、管理后台接口适合 HTTP;设备状态、实时告警和低带宽上报更适合 MQTT。很多系统会混用,别试图用一个协议解决所有问题。
Broker 是不是单点?
逻辑上 Broker 是中心节点,所以单机 Broker 确实可能成为单点。生产环境可以用集群、负载均衡和客户端自动重连降低风险。边界在于 MQTT 长连接有会话状态,故障切换不像无状态 HTTP 那么简单。要验证 Broker 高可用,必须实际测试节点宕机、网络抖动和客户端重连后的消息表现。
MQTT 基于 TCP,为什么还需要 QoS?
TCP 只能保证一条连接上的字节流可靠、有序,不能保证应用消息在断线、重连、Broker 转发和订阅者离线时符合业务预期。MQTT QoS 是应用层的交付语义,用来处理确认、重传和重复问题。踩坑点是以为 TCP 可靠就等于业务可靠,结果设备掉线时消息丢了还不知道。QoS 要和持久会话、离线队列、业务幂等一起看。
MQTT 适合传大文件吗?
不适合。MQTT 更适合小消息、高频状态和控制指令,大文件会占用 Broker 内存、网络和队列资源。文件上传、固件下载更适合 HTTP、对象存储或专门的 OTA 通道。实际取舍是:MQTT 可以发文件地址、版本号和下载指令,但不要把固件二进制直接塞进 MQTT payload。
新手接入 MQTT 最容易忽略什么?
最容易忽略主题规范和安全配置。刚开始大家会用 test/#、匿名连接和公网 1883 调试,跑通很快,但上线后权限和排障都很痛苦。另一个坑是没有给消息设计唯一 ID,遇到 QoS 1 重复投递时无法去重。把 Client ID、topic、QoS、ACL 和日志字段提前约定好,比后期补救省很多时间。