Google Cloud IoT 控制台日志中有许多 "MQTT disconnect - ALREADY_EXISTS" 错误

Many "MQTT disconnect - ALREADY_EXISTS" error in Google Cloud IoT console log

我在我的项目中使用 Google IoT Core 作为 MQTT 代理,将基于 Atmel MCU 的物联网嵌入式设备连接到 Goole Cloud Plattform。

在平台日志中,我遇到很多 "MQTT DISCONNECT" 错误。

jsonPayload: {
  disconnectType: "SERVER"   
  eventType: "DISCONNECT"   
  protocol: "MQTT"   
  resourceName: "projects/xxxxxxx/locations/europe-west1/registries/xxxxxxxx/devices/1234567890"   
  serviceName: "cloudiot.googleapis.com"   
  status: {
   code: 6    
   description: "ALREADY_EXISTS"    
   message: "SERVER: The connection was closed because there is another active connection with the same device ID."    
  }
 }
labels: {
  device_id: "d1234567890"   
 }
 logName: "projects/xxxxxxxxx/logs/cloudiot.googleapis.com%2Fdevice_activity" 

设备启动并连接到MQTT服务器时产生错误。 尽管有这个错误,连接成功,订阅主题和消息发布也是如此。

我知道之前的连接没有正常关闭,但是嵌入式设备的本质是不可能的,它意味着一直连接,最终通过断开电源关闭(所以它不能发送一个之前断开与服务器的消息)。

设备 ID 在每次重新连接时始终相同,但每个设备都是唯一的;我在一些 Google 的示例中使用芯片序列号。

我的问题是,如果有这个错误的解决方案,在开发阶段可以忽略,但在生产环境中将是不需要的行为。

我认为您出于 "hygiene" 原因希望排除特定错误。我在想,当你注视日志时,你会对错误类型的消息保持警惕,而这种性质的消息会被认为是分散注意力的。

幸运的是,Stackdriver 日志记录提供了排除功能。您可以提供一组过滤器,使 Stackdriver 丢弃您明确选择不保留的日志条目。此处对此进行了详细描述:

https://cloud.google.com/logging/docs/exclusions

我发现页面上的插图特别有用。

您可能想要做的是制定一个与此类消息完全匹配的查询。我还没有测试过,但大致是这样的:

logName = 'cloudiot.googleapis.com%2Fdevice_activity'
jsonPayload.eventType = 'DISCONNECT'
jsonPayload.status.description= 'ALREADY_EXISTS'

一旦您有一个仅匹配要排除的邮件的过滤器表达式,您就可以将该过滤器用作排除过滤器。

与设备桥接器的 MQTT 连接具有一些可能导致断开连接的特殊属性。对于设备连接,每个设备只能连接一个(或设备 ID,对于网关而言)。在我看来,您尝试连接同一台设备两次,结果断开连接。

您的客户端可能试图打开两个连接,或者您正在连接第二个客户端。如果您连接同一台设备两次,该设备将断开连接。也许您的客户端设置为打开多个通道,或者您的应用程序逻辑正在重新连接而不断开连接。

断开连接有多种其他原因,例如,如果您尝试使用不正确的 QoS 或无效主题进行发布,但这似乎并不是给定的发布正在处理后续连接。