发送mqtt QoS 2的消息时,消息会丢失吗?如何保证消息传输不丢失思路

  • Post author:
  • Post category:其他



官网文档

解决“丢失消息”这一问题。 消息是非持久消息、发送至错误的位置还是从未发送? 错误编写的客户机程序可能会丢失消息。



开始之前

您有多肯定您所发送的消息已丢失? 您可以推断是因为未收到消息而丢失了此消息吗? 如果消息是发布,而此消息丢失,那么该消息由发布者发送,还是发送到订户? 或者是因为预订丢失了,而代理未将该预订的发布发送至订户?

如果解决方案涉及到使用集群或者发布/预订层次结构的分布式发布/预订,那么有许多配置问题可能会导致丢失消息。

如果已发送具有至少一次或至多一次服务质量的消息,那么您认为丢失的消息有可能没有按预期方式传递。 不太可能已经从系统中错误地删除了此消息。 有可能未能创建您期望的发布或预订。

在确定“丢失消息”这一问题时,您执行的最重要的步骤是确认此消息是否确实已丢失。 重现该场景,丢失更多消息。 使用至少一次或至多一次服务质量来消除系统废弃消息的所有情况。



关于本任务

可以通过四条途径来诊断“丢失消息”这一问题。

  1. 发出消息之后无需等待应答消息按设计那样工作。 系统有时候会废弃发出消息之后无需等待应答消息。
  2. 配置:在分布式环境中使用正确的权限来设置发布/预订并不简单。
  3. 客户机编程错误: 消息传递的责任不仅仅由 IBM®编写的代码负责。
  4. 如果您已用尽所有这些可能性,那么可以决定让 IBM 支持人员参与。



过程

  1. 如果丢失的消息具有 触发并忘记 服务质量,请设置 至少一次 或 最多一次 服务质量。 尝试再次丢失此消息。

    • 在许多情况下,IBM MQ会丢弃使用触发和忘记

      服务质量发送的消息:

      • 通信中断,并且通道已停止。
      • 队列管理器已关闭。
      • 消息数过多。
    • 发出消息之后无需等待应答消息的传递依赖于 TCP/IP 的可靠性。 TCP/IP 将继续反复发送数据包,直到传递的数据包获得确认为止。 如果 TCP/IP 会话已中断,那么服务质量为发出消息之后无需等待应答的消息就会丢失。 当客户机或服务器停机、发生通信问题或者防火墙使会话断开连接时,会话就可能会中断。

  2. 检查客户机是否正在重新启动先前会话,以便使用 至少一次 或 最多一次 服务质量再次发送未传递的消息。

    1. 如果客户机应用程序正在使用 Java SE MQTT 客户机,请检查它是否将 MqttClient.CleanSession 设置为

      false
    2. 如果您正在使用不同的客户机库,请检查是否正在正确地重新启动会话。
  3. 检查客户机应用程序是否是重新启动同一会话,而不是错误地启动其他会话。

    要再次启动同一个会话,

    cleanSession = false

    、Mqttclient.clientIdentifier 和 MqttClient.serverURI 必须与前一个会话相同。



总结:

  1. cleanSession = true 客户端未连接的情况下,发送topic,连接后并不会收到消息,说明被丢弃。
  2. cleanSession = false 客户端未连接,发送topic,连接后会根据发送方QOS来检查是否收消息。该方案一定要考虑实际项目需求。举例:

    用户A发送一个开门指令,客户端当前没有连接,过了半个小时后连接上收到开门指令,已经过了半个小时还需要开门吗?所以可以在接收方做一个utc超时处理逻辑。



如何在程序端尽量保证接收成功

发送topic成功后,程序并不知道是否已经到达,所以做以下方案

  1. 必须保证执行的,可在发送topic后,做一个接收的topic,通过消息ID来确认客户端已经处理。
  2. 可以在发送前判断连接是否正常。 举例:指定给A发送,在发送前,调用mqtt客户端的API,获取A是否已经连接,连接则发送,未连接则抛出异常。



版权声明:本文为san13219091原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。