MQTT 是已连接的设备应用的 OASIS 标准协议,它使用发布和订阅代理架构提供双向消息传递。MQTT 协议是轻量级的,可减少网络开销,并且 MQTT 客户端非常小,可最大限度地减少使用受限设备上的资源。对于想要在 Google Cloud 上支持已连接的设备应用的组织,一个解决方案是在 Compute Engine 或 GKE 上运行独立的 MQTT 代理。如需在组织中部署 MQTT 代理,您需要做出一些会影响整体架构的关键决策:特别是负载均衡和部署环境。本文档介绍用于在 Google Cloud 上部署 MQTT 代理(MQTT 部署中的核心应用)的架构。本文档还介绍您在部署此代理时需要做出的决策,以及它们对架构的影响。
本文档是系列文档中的一篇,该系列介绍了 Google Cloud 上的 IoT 架构。本系列中的其他文档包括以下内容:
- Google Cloud 上的关联设备架构概览
- Google Cloud 上的独立 MQTT 代理架构(本文档)
- Google Cloud 上的 IoT 平台产品架构
- 在 Google Cloud 上运行 IoT 后端的最佳做法
- 将 Pub/Sub 架构上的设备迁移到 Google Cloud
- 自动预配和配置边缘与裸机系统和服务器的最佳做法
下图展示了在 Google Cloud 上运行的 MQTT 代理架构。
上图中的架构组成:
- MQTT 代理部署为含有三个实例集群,这些实例连接到 Cloud Load Balancing 服务。对于云负载均衡器,您可以从多种负载均衡产品中选择一个,本文档稍后将对此进行介绍。
- 代理集群包含设备凭据存储区以及设备身份验证和授权服务。集群通过 Dataflow 或 Pub/Sub 与后端工作负载连接。
- 在客户端,边缘网关通过基于 TLS 的 MQTT 在边缘设备和 MQTT 代理集群之间提供双向通信。
我们一般建议您在集群中为此架构部署 MQTT 代理应用以实现可扩缩性。聚簇功能、纵向扩容和缩容集群管理、数据同步以及网络分区处理等因素由特定的代理实现(例如 HiveMQ、EMQX、VerneMQ、mosquito 及其他)解决。
架构注意事项和选择
以下部分介绍了您必须针对独立 MQTT 代理架构进行的不同架构选择和考虑,以及这些选择对架构的影响。
已连接的设备
连接到互联网的边缘设备将其遥测事件和其他信息发布到 MQTT 代理。为了实现本文档中所述的独立 MQTT 代理架构,设备需要具有 MQTT 客户端、用于 TLS 身份验证的服务器证书公钥以及进行 MQTT 代理身份验证所需的凭据。
此外,边缘设备通常具有本地传感器、本地数据系统以及没有互联网访问权限或 IP 连接的其他设备的连接器。例如,边缘设备可以充当其他本地受限设备的网关,这些设备使用 BLE、有线连接或其他近场协议连接到网关。联网设备架构的详细规范不在本指南的讨论范围内。
负载均衡
在此架构中,公共负载均衡服务和 MQTT 代理集群之间配置外部负载均衡服务。此服务提供了多项重要的网络功能,包括跨后端节点的传入连接分配、会话加密和身份验证。
Google Cloud 支持多种负载均衡器类型。如需为您的架构选择最佳负载均衡器,请考虑以下事项:
mTLS。mTLS 可处理加密和设备身份验证方法,而标准 TLS 仅处理加密,并且需要单独的设备身份验证方法:
- 如果应用使用 mTLS 进行设备身份验证并且需要终结 TLS 隧道,我们建议您使用外部直通式网络负载均衡器或具有目标 TCP 代理的外部代理网络负载均衡器。外部代理网络负载均衡器会终止 TLS 会话并代理与代理节点的连接,以及消息中包含的任何身份验证凭据。如果您需要将客户端连接信息作为身份验证方案的一部分,则可以通过启用 PROXY 协议在后端连接中保留它。
- 如果应用不使用 mTLS,我们建议您使用具有目标 SSL 代理的外部代理网络负载均衡器将外部 TLS 和 SSL 处理分流到负载均衡器。外部代理网络负载均衡器会终止 TLS 会话并代理与代理节点的连接,以及消息中包含的任何身份验证凭据。如果您需要将客户端连接信息作为身份验证方案的一部分,则可以通过启用 PROXY 协议在后端连接中保留它。
HTTP(S) 端点。如果您需要公开 HTTP(S) 端点,我们建议您为这些端点配置单独的外部应用负载均衡器。
如需详细了解 Cloud Load Balancing 支持的负载均衡器类型,请参阅 Google Cloud 负载负载均衡器摘要。
负载均衡策略
任何负载均衡服务都会根据多种算法或均衡模式,跨集群中的节点分配来自边缘设备的连接。对于 MQTT,会话亲和性负载均衡策略优于随机负载均衡。由于 MQTT 客户端-服务器连接是永久性双向会话,因此状态会在停止连接的代理节点上维护。在聚簇配置中,如果客户端断开连接,然后重新连接到其他节点,则会话状态会移至新节点,这会增加集群的负载。使用会话亲和性负载均衡可以在很大程度上避免此问题。如果客户端经常更改其 IP 地址,连接可能会中断,但在大多数情况下,会话亲和性更适合 MQTT。会话亲和性适用于所有 Cloud Load Balancing 产品。
设备身份验证和凭据管理
MQTT 代理应用会独立于 Google Cloud 处理设备身份验证和访问权限控制。代理应用还提供自己的凭据存储和管理界面。MQTT 协议支持初始 Connect 数据包中的基本用户名和密码身份验证,代理实现也会经常使用这些字段来支持其他形式的身份验证,例如 X.509 证书或 JWT 身份验证。MQTT 5.0 还增加了对使用质询/响应式身份验证的增强型身份验证方法的支持。使用的身份验证方法取决于 MQTT 代理应用的选择和已连接的设备使用场景。
无论代理使用哪种身份验证方法,代理都会维护设备凭据存储区。此存储区可以位于本地 SQL 数据库或平面文件中。某些代理(包括 HiveMQ 和 VerneMQ)也支持使用代管式数据库服务,例如 Cloud SQL。您需要一个单独的服务来管理设备凭据存储区并处理与其他身份验证服务(如 IAM)的集成。此服务的开发不在本指南的讨论范围内。
如需详细了解身份验证和凭据管理,请参阅在 Google Cloud 上运行 IoT 后端的最佳做法。
后端工作负载
任何已连接的设备用例都包含一个或多个后端应用,这些应用使用从已连接的设备注入的数据。有时,这些应用还需要向设备发送命令和配置更新。在本文档中的独立 MQTT 代理架构中,传入数据和传出命令均通过 MQTT 代理进行路由。代理的主题层次结构中具有不同的主题,用于区分数据和命令。
您可以通过多种方式之一在代理与后端应用之间发送数据和命令。如果应用本身支持 MQTT,或者可以修改为支持 MQTT,则应用可以直接订阅代理作为客户端。通过此方法,您可以使用您的应用接收来自已连接的设备的数据和向其发送命令,从而直接使用 MQTT Pub/Sub 双向消息传递功能。
如果您的应用不支持 MQTT,则还有其他几个选项。在本文档介绍的架构中,Apache Beam 提供了一个 MQTT 驱动程序,可让您与 Dataflow 和其他 Beam 部署进行双向集成。许多代理还具有支持与 Google Pub/Sub 等服务集成的插件功能。有些代理通常支持数据集成,但有些代理支持双向集成。
使用场景
MQTT 代理架构特别适合以下部分中介绍的设备使用场景。
从异构设备进行基于标准的数据注入
当您要收集和分析大量异构设备的数据时,MQTT 代理通常是很好的解决方案。由于 MQTT 是广泛采用和实现的标准,因此许多边缘设备内置了相应支持;而轻量级 MQTT 客户端可以为不支持 MQTT 的设备添加支持。发布和订阅范式也是 MQTT 标准的一部分,因此支持 MQTT 的设备可以利用此架构,而无需额外的实现工作。相比之下,连接到 Pub/Sub 的设备必须实现 Pub/Sub API 或使用 Pub/Sub SDK。因此,在 Google Cloud 上运行符合标准的 MQTT 代理提供了一种从各种设备收集数据的简单解决方案。
如果已连接的设备不是由您的应用控制,而是由第三方控制,那么您可能无权访问设备系统软件,而设备本身的管理由另一方负责。在这种情况下,我们建议您运行 MQTT 代理,并向第三方提供身份验证凭据以设置设备到云的通信通道。
多方应用集成的双向通信
MQTT 的双向消息传递功能非常适合多方移动应用使用场景,例如按需食品交付或大规模 Web 聊天应用。MQTT 的协议开销较低,并且 MQTT 客户端的资源需求较低。MQTT 还提供发布和订阅路由、多种服务质量 (QoS) 级别、内置消息保留和广泛的协议支持。MQTT 代理可以是按需服务应用以及类似使用场景的可扩缩消息传递平台的核心组件。
边缘到云集成消息传递
由于 MQTT 提供的标准化和低开销,这也是集成本地和云消息传递应用的理想解决方案。例如,工厂经营者可以在本地环境中部署多个 MQTT 代理,以连接到传感器、机器、网关和其他受防火墙保护的设备。本地 MQTT 代理可以处理本地基础架构的所有双向命令和控制以及遥测消息传递。本地代理还可以通过与云中并行 MQTT 代理集群之间的双向订阅进行连接,从而实现云与边缘环境之间的通信,而无需向公共互联网公开本地设备和系统。
后续步骤
- 了解如何使用 Intelligent Products Essentials 在 Google Cloud 上连接设备和构建 IoT 应用。
- 了解自动预配和配置边缘与裸机系统和服务器的实践。
- 如需查看更多参考架构、图表和最佳实践,请浏览云架构中心。