本部分介绍设备如何使用 MQTT 网桥与 Cloud IoT Core 通信。如需大致了解 HTTP 和 MQTT,请参阅协议。
请务必参阅 API 文档,详细了解本部分中介绍的每种方法。 另请参阅与 MQTT 相关的示例。
如需通过 MQTT 网桥发布,请执行以下操作:
在您的设备上安装 MQTT 客户端。
在您的设备上下载 MQTT 服务器证书。
配置 MQTT 客户端以向 Cloud IoT Core 验证设备的身份。
通过
mqtt.googleapis.com
或长期支持网域发起 TLS 握手。
MQTT 服务器
Cloud IoT Core 通过运行侦听端口 mqtt.googleapis.com:8883
的代管式代理来支持 MQTT 协议。端口 8883 是 IANA 为安全 MQTT 连接保留的标准 TCP 端口。与此端口的连接必须使用 TLS 传输,Eclipse Paho 等开源客户端支持该传输。
如果端口 8883 被防火墙阻止,您还可以使用端口 443:mqtt.googleapis.com:443
。
服务质量 (QoS)
MQTT 规范描述了三个服务质量 (QoS) 级别:
- QoS 0,最多传送一次
- QoS 1,至少传送一次
- QoS 2,仅传送一次
Cloud IoT Core 不支持 QoS 2。发布 QoS 2 消息会关闭连接。使用 QoS 2 订阅预定义主题会将 QoS 级别降级为 QoS 1。
QoS 0 和 1 在 Cloud IoT Core 中的功能如下所示:
- 成功发送到 Cloud Pub/Sub 后,QoS 为 1 的
PUBLISH
消息将由PUBACK
消息确认。 - QoS 为 0 的
PUBLISH
消息不需要PUBACK
响应,如果消息传送路径存在任何抖动(例如,如果 Cloud Pub/Sub 暂时不可用),则可能会被丢弃。 - Cloud IoT Core MQTT 网桥会维护一个未传送的消息小缓冲区,以便于重试。如果缓冲区已满,QoS 为 1 的消息可能会被丢弃,并且不会向客户端发送
PUBACK
消息。客户端应重新发送该消息。
对于设备配置,QoS 级别如下所示:
- 当 QoS 为 0 时,给定的配置版本只会发布到设备一次。如果设备未收到配置,则必须重新订阅。因此,当配置频繁更新(大约几秒或几分钟)并且设备没有必要接收每个更新时,值为 0 的 QoS 非常有用。
- 当 QoS 为 1 时,将重试最新的配置更新,直到设备使用 PUBACK 确认它。如果在确认旧配置之前推送了新配置,则系统不会重新传送旧配置;而是会递送新配置(并重新传送)。此级别是设备配置的最安全模式:它保证设备最终将获得最新配置。
下载 MQTT 服务器证书
如需使用 TLS 传输,设备必须验证 Cloud IoT Core 服务器证书,以确保它们与 Cloud IoT Core 而不是冒名者进行通信。以下证书包支持验证:
mqtt.googleapis.com
的完整 Google 根 CA 认证软件包 (128 KB)。- 此软件包会建立与 Google 产品和服务(包括 Cloud IoT Core)通信的信任链。
- 具有完整根 CA 认证软件包的设备直接与 MQTT 服务器通信。
- 此软件包会定期更新。
mqtt.2030.ltsapis.goog
的 Google 最小根 CA 集(小于 1 KB)。最小根 CA 集包括主证书和备份证书。- 此集适用于具有内存限制的设备(如微控制器),并仅建立与 Cloud IoT Core 通信的信任链。
- 具有最小根 CA 集的设备通过长期支持网域与 Cloud IoT Core 进行通信。
- 一直到 2030 年,此集都将保持不变(主证书和备用证书不会更改)。为了提高安全性,Google 信任服务可能会随时在主证书和备用证书之间切换,恕不另行通知。
将 Google 根 CA 证书下载到您的设备后,您可以配置 MQTT 客户端以对设备进行身份验证、连接到 MQTT 服务器,以及通过 MQTT 网桥进行通信。
配置 MQTT 客户端
MQTT 客户端通过连接到 MQTT 网桥来对设备进行身份验证。如需配置 MQTT 客户端以对设备进行身份验证,请执行以下操作:
- 将 MQTT 客户端 ID 设置为完整的设备路径:
projects/PROJECT_ID/locations/REGION/registries/REGISTRY_ID/devices/DEVICE_ID
- 将 MQTT 客户端与 MQTT 服务器证书关联。
- 将 MQTT 主机名设置为
mqtt.googleapis.com
或长期支持网域(如果您使用的是最小根 CA 集)。 - 指定用户名。MQTT 网桥会忽略用户名字段,但一些 MQTT 客户端库不会发送密码字段,除非指定用户名字段。为获得最佳效果,请提供
unused
或ignored
等任意用户名。 - 设置密码。密码字段必须包含 JWT。
以下示例展示了如何配置 MQTT 客户端以对设备进行身份验证:
使用长期 MQTT 网域
长期支持 (LTS) 网域可让您长时间使用一项 TLS 配置。您可以设置 MQTT 客户端一次,配置 MQTT 客户端以通过 LTS 网域发布消息,然后在支持的时间范围内通过 MQTT 网桥持续通信。
当前的活跃 LTS 网域是 mqtt.2030.ltsapis.goog
。支持此 LTS 网域,直到 2030 年。
如需使用 LTS 网域,请执行以下操作:
配置 MQTT 客户端以通过 LTS 网域发布消息。
- 配置 MQTT 客户端以向 Cloud IoT Core 验证设备的身份。
- 配置设备时,将最小根 CA 集的主证书和备用证书与 MQTT 客户端关联。
在端口 8883 或 443 上通过
mqtt.2030.ltsapis.goog
发起 TLS 握手。请至少使用以下 TLS 功能。- TLS 1.2
- P-256,使用 SHA-256 作为证书密钥和哈希算法
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,为加密套件使用 P-256 和未压缩点
- 服务器名称指示 (SNI)
- 基于 TCP 或 UDP 的 DNS
如需详细了解如何保护 MQTT 流量(包括发送到 LTS 网域的消息),请参阅设备安全建议。
发布遥测事件
设备配置 MQTT 客户端并连接到 MQTT 网桥后,可以通过以下格式向 MQTT 主题发布 PUBLISH
消息来发布遥测事件:
/devices/DEVICE_ID/events
设备 ID 是在 MQTT 客户端 ID 中指定的设备的字符串 ID。设备 ID 区分大小写。
发布到此 MQTT 主题的消息将转发到相应注册表的默认遥测主题。默认的遥测主题是在注册表资源的 eventNotificationConfigs[i].pubsubTopicName
字段中指定的 Cloud Pub/Sub 主题。如果不存在默认的 Pub/Sub 主题,则已发布的遥测数据将丢失。如需向其他 Cloud Pub/Sub 主题发布消息,请参阅将遥测事件发布到其他 Cloud Pub/Sub 主题。
转发的消息数据字段包含设备发布的消息的副本,并且系统会将以下消息特性添加到 Cloud Pub/Sub 主题中的每条消息:
属性 | 说明 |
---|---|
deviceId |
设备的用户定义字符串标识符,例如 thing1 。设备 ID 在注册表中必须是唯一的。 |
deviceNumId |
服务器生成的设备数字 ID。创建设备时,Cloud IoT Core 会自动生成设备数字 ID。具有全局唯一性,且不可修改。 |
deviceRegistryLocation |
设备注册表的 Google Cloud Platform 区域,例如 us-central1 。 |
deviceRegistryId |
设备注册表的用户定义字符串标识符,例如 registry1 。 |
projectId |
注册表和设备所属的云项目的字符串 ID。 |
subFolder |
该子文件夹可用作事件类别或分类。对于 MQTT 客户端,子文件夹是 DEVICE_ID/events 后面可直接复制的子主题。例如,如果客户端发布到 MQTT 主题 /devices/DEVICE_ID/events/alerts ,则子文件夹为字符串 alerts 。 |
以下示例展示了如何通过 MQTT 连接发送 PUBLISH
消息:
将遥测事件发布到其他 Cloud Pub/Sub 主题
设备可以将数据发布到其他 Cloud Pub/Sub 主题。默认情况下,发布到 /devices/DEVICE_ID/events
的 MQTT 消息会转发到相应注册表的默认遥测主题。您可以在 MQTT 主题中指定子文件夹,以将数据转发到其他 Cloud Pub/Sub 主题。该子文件夹是 /devices/DEVICE_ID/events
后面的子主题。
发布到子文件夹的消息会转发到具有相同名称的 Cloud Pub/Sub 主题。相应的注册表必须使用 Cloud Pub/Sub 主题进行配置;否则,消息会转发到默认 Cloud Pub/Sub 主题。
在以下情况下,消息会转发到默认 Cloud Pub/Sub 主题,而不是其他 Cloud Pub/Sub 主题:
- 未在 MQTT 主题中指定子文件夹
- 在 MQTT 主题中指定了子文件夹,但它在设备注册表中没有匹配的 Pub/Sub 主题
例如,如果设备发布到 MQTT 主题 /devices/DEVICE_ID/events/alerts
,则子文件夹为字符串 alerts
。如果 eventNotificationConfigs[i].subfolderMatches
和 eventNotificationConfigs[i].pubsubTopicName
字段都设置为 alerts
,则消息将转发到其他 Cloud Pub/Sub 主题。否则,消息会转发到默认的 Cloud Pub/Sub 主题。
设置设备状态
已连接的设备可以通过向以下 MQTT 主题发出 PUBLISH
消息来报告设备状态:
/devices/DEVICE_ID/state
如需对状态消息进行分类和检索,请使用设备状态主题配置注册表。设备状态主题是在 StateNotificationConfig.pubsubTopicName
字段中指定的 Cloud Pub/Sub 主题。如果注册表配置了设备状态主题,则这些消息将尽力转发到匹配的 Cloud Pub/Sub 主题。
如需详细了解如何检索状态消息,请参阅获取设备状态。
限制 MQTT 流量
Cloud IoT Core 会限制生成过多负载的项目。如果设备在未等待的情况下重试失败的操作,则可能会触发限制,影响同一 Google Cloud 项目中的所有设备。
对于重试,我们强烈建议您使用引入的抖动实现截断指数退避算法。
Keep-alive
从客户端发送初始 MQTT CONNECT
消息时,您可以提供可选的“keep-alive”值。此值是一个时间间隔(以秒为单位),在此期间,代理期望客户端发送消息(如 PUBLISH
消息)。如果在时间段内未从客户端向 Broker 发送任何消息,则 Broker 会自动关闭连接。请注意,您指定的 keep-alive 值乘以 1.5,因此,设置 10 分钟的 keep-alive 实际上会导致 15 分钟的间隔。
如需了解详情,请参阅 MQTT 规范。
客户端设置
Cloud IoT Core 不提供自己的默认 keep-alive 值;如果您选择指定 keep-alive 间隔,则必须在客户端中进行设置。
为获得最佳结果,请将客户端的 keep-alive 间隔设置为最小值(60 秒)。许多开源客户端库(包括 C、Python、Node.js、Java 的 Paho MQTT 库默认使用 60 秒。
空闲时间限制
与 keep-alive 间隔不同,Cloud IoT Core 有自己的空闲时间限制(20 分钟)。根据此限制,如果客户端在 20 分钟内未发送任何消息,则客户端连接将自动终止,即使 keep-alive 间隔更长也是如此。如果未提供 keep-alive 值,则默认的空闲超时值 20 分钟仍然有效。
问题排查
如果在连接时遇到问题,请参阅问题排查。