TBMQ支持两类客户端:DEVICE 和 APPLICATION。 该分类根据实际IoT部署中的典型使用模式,用于优化消息处理、可靠性与资源利用。 结合我们在IoT生态中的经验,大多数客户端均可归入其中一类。
-
DEVICE客户端主要大量发布消息,仅订阅少量主题且消息率较低。 通常对应频繁向TBMQ发送数据的IoT设备或传感器。
-
APPLICATION客户端侧重于订阅高消息率主题。 常在离线时需持久化消息以便后续投递,保证关键数据可用。 APPLICATION客户端常用于实时分析、数据处理或其他应用层功能。
例如,一个每秒发布读数的温度传感器通常是DEVICE客户端,而一个订阅数千个传感器聚合数据的云分析服务则是APPLICATION客户端。
通过将客户端分为这两种不同类型,我们可以更好地定制TBMQ以适应每种用例的特定需求和性能期望。 这种客户端分类简化了不同IoT场景的实现,从而优化了整体系统性能。
客户端类型的确定发生在处理_CONNECT_报文期间,客户端认证在识别客户端类型中起着关键作用。有关客户端认证的更多详情可在安全指南中找到,该指南提供了保护客户端连接的全面信息。
如果Basic和TLS认证均被禁用,连接的客户端将始终被分配为DEVICE类型。
然而,当启用Basic或TLS认证时,客户端类型由认证过程中使用的MQTT凭据决定。
每个MQTT客户端凭据包含一个clientType字段,明确定义客户端类型。
有关创建MQTT凭据的分步说明,请参阅指定的指南。
客户端持久化
所有MQTT客户端发布的消息都持久存储在tbmq.msg.all Kafka主题中。
这些消息的后续处理取决于客户端类型以及客户端是持久的还是非持久的。
TBMQ使用Kafka消费者主动从tbmq.msg.all主题轮询消息,随后将这些消息转发给预期接收者。
然而,持久客户端和非持久客户端之间的处理逻辑有所不同。
-
对于非持久客户端,消息直接发布给已订阅的客户端。
-
持久客户端维护一个超越单次连接存在的会话状态,允许它们即使在离线时也能接收消息。 这种持久性使TBMQ能够确保客户端重新连接后的消息投递。因此,对此类客户端的消息处理采用不同的方法。 但请注意,如果订阅客户端是持久的且以QoS级别_0(_AT_MOST_ONCE)订阅,与该订阅关联的所有消息将直接投递给客户端,无需任何额外步骤。 对于QoS级别高于0的持久订阅者也是如此,前提是发布者以QoS级别0传输消息。 此行为是QoS级别降级的结果。
通过利用Kafka作为中间消息存储并根据客户端特性采用不同的处理策略,TBMQ优化了消息投递,确保持久和非持久客户端场景中的可靠通信。
Device客户端
DEVICE类型的客户端可表现为持久或非持久行为,取决于_CONNECT_报文中指定的设置,如客户端持久化部分所述。
对于持久DEVICE客户端,相关消息会被发送到名为tbmq.msg.persisted的额外Kafka主题。
为了便于向在线和离线客户端投递消息,专用Kafka消费者持续从tbmq.msg.persisted主题轮询消息。
这些消息经过处理后持久存储在Redis数据库中,然后分发给已订阅的在线客户端。
这种方法确保在线和离线客户端都能接收所有消息,保证不同客户端状态下的一致消息投递。
当离线客户端重新连接到broker时,它们会收到离线期间存储在Redis中的持久消息。
离线客户端重连时接收的消息数量可通过修改MQTT_PERSISTENT_SESSION_DEVICE_PERSISTED_MESSAGES_LIMIT环境变量来控制。
这使得可以微调离线客户端的消息检索行为,自定义它们重连时接收的消息数量。
Application客户端
虽然TBMQ的设计假设APPLICATION客户端需要持久化,但此行为并非强制执行。 如果客户端被认证为APPLICATION类型但发起非持久会话,消息仍会投递给客户端; 但不会应用额外的持久化机制。这意味着如果客户端在投递期间断开连接或变得不可用,消息可能会丢失。 为了提醒非持久APPLICATION客户端的影响,在客户端会话详情页面上会显著显示告警信息。
从tbmq.msg.all Kafka主题轮询消息后,TBMQ将消息转发到每个持久APPLICATION客户端的专用Kafka主题。
这些按客户端划分的主题仅在客户端被认证为APPLICATION类型且使用持久会话时才会自动创建。
此主题的命名规则遵循以下格式:
1
tbmq.msg.app.$CLIENT_ID
其中$CLIENT_ID代表连接客户端关联的唯一客户端ID。
重要提示: 如果客户端ID包含非字母数字字符,将使用从客户端ID派生的哈希值来构建主题。 这确保了与主题命名规范的兼容性,因为某些特殊字符可能不被主题名称允许或支持。 通过从客户端ID生成哈希值,任何不兼容或禁止的字符都能得到有效处理,确保正确的主题构建和功能。
1
tbmq.msg.app.$CLIENT_ID_HASH
上述行为(当客户端ID包含特殊字符时使用哈希值构建主题)由TB_APP_PERSISTED_MSG_CLIENT_ID_VALIDATION环境变量控制。
默认情况下,此变量已启用,意味着验证过程处于活跃状态,确保正确的主题创建。
然而,如果你选择通过将变量设置为_false_来禁用此验证,系统将不再为客户端ID中包含特殊字符的客户端创建Kafka主题,导致相应主题创建失败。
在配置环境和处理包含特殊字符的客户端ID时,请务必考虑这一点。
为确保高效处理和最佳性能,一个独立的Kafka消费者持续从上述主题轮询消息。 该消费者负责将消息投递给对应的APPLICATION客户端。 通过在独立线程中处理每个APPLICATION客户端,此方法实现了增强的性能和流畅的消息投递。
总结
下表总结了TBMQ中DEVICE和APPLICATION客户端之间的主要差异,包括它们的角色、持久化行为、消息路由策略和典型用例。
| 特性/行为 | DEVICE客户端 | APPLICATION客户端 |
|---|---|---|
| 典型角色 | 主要发布数据;以适度流量订阅(如传感器或IoT设备) | 数据消费者(如分析系统、规则引擎) |
| 持久化支持 | 持久或非持久 | 预期为持久化 |
| 默认类型(未认证客户端) | 是 | 否 |
| 消息存储(非持久客户端) | 无持久化 | 无持久化 |
| 消息存储(持久客户端) | Redis | 专用Kafka主题 |
| 离线时消息投递 | 是(如持久)通过Redis | 是(如持久)通过Kafka |
| 常见用例 | IoT传感器、遥测发布者 | 分析系统、实时数据处理器 |