MQTT 5.0到期消息Message Expiry

Publish: October 16, 2020 Category: 编程 No Comments

MQTT 5.0规范中有一个整洁的小功能,称为消息过期(或消息过期间隔)。

互联网上已经对此进行了多次解释。它允许发布者在其发送的任何消息中添加有效期限。有时候,我们对功能有误解。误解是MQTT 3.1.1协议缺少Message Expiry,而现在它已存在于5.0中,它将取代并替换保留的消息和其他持久会话功能。好吧,没那么快。

您很可能会从传统企业消息传递系统中了解消息过期(或TTL,生存时间)。规范的示例在这里:消息过期模式。

传统消息过期模式与MQTT

此模式的应用程序主要是这样的:

  • 首先,您希望使用者在特定时间范围内处理作业(应用程序消息)。
  • 其次,您希望将应用程序消息转发到dead lettering队列,以防使用者无法及时处理它。从dead lettering队列中,您的后端系统可以处理该消息并重新触发作业或任何其他需要的操作。
    现在,MQTT没有队列概念,当然也没有dead lettering队列概念!因此,我们从一开始就面临着截然不同的情况。您不能只配置dead lettering队列(或dead lettering主题)。顺便说一下,这也是原因,MQTT与其他系统一样,除了消息TTL之外没有“队列TTL”。 (请注意,它具有Session Expiry,这又是完全不同的东西)。

MQTT 5.0明确声明“dead lettering”不属于规范的一部分:

“如果数据包被丢弃而没有发送,则服务器可以将丢弃的数据包放置在'dead lettering队列'中或执行其他诊断操作。这些操作不在本规范的范围之内。”

这会给我们留下半熟无用的功能吗?

一点都不。首先,如果您需要一些dead lettering功能,您仍然可以使用客户端应用程序组件(或代理插件)来实现。

其次,显然还有一些应用程序可以从简单的基于时间的到期中受益,而无需dead lettering队列。假设您有一个移动应用程序,在您向他们发送推送通知后,它们已连接到MQTT代理。您可以在应用程序消息中向他们发送基于时间的优惠券报价。如果优惠券到期,那么以后的人完全不需要得到该消息。

使用Message Expiry还可以帮助您更有效地管理代理状态。如果您知道永远不需要消息,则可以告诉代理并允许它在脱机队列中存储和管理更少的消息。

MQTT(SCADA)的性质

进一步了解MQTT的性质,您可以看到它与传统EAI和协议(例如AMQP)的区别,即使在消息过期(Message Expiry)这样的小功能中也是如此。要了解这一点,您需要研究MQTT的来源,即监督控制和数据采集(SCADA)。

在SCADA中,主要问题是SCADA主机是否知道其管理的现场设备的状态。报告的值是“好”还是“陈旧”(未知)? SCADA主机需要的是LGV(最后一个好的价值)。而且,即使该设备已多次断开连接,即使该设备已连续几天没有发送状态更新,也需要确定LGV。所有会话状态持久性的目的都在于:确保LGV并允许按异常报告样式的消息传递,而不是定期轮询当前字段值状态。诸如保留消息功能(始终保留最后传入的消息)之类的功能可能足以应付此类情况。

另一方面,当您的用例与之完全相反时,给应用程序消息一个有效期是毫无意义的:避免过时的值。 (或者,与仅轮询值相比,至少没有太多优势)。

如果这对您来说没有太大意义,请不要担心。我的意思是记住MQTT的来源通常很有用。有时我们假设消息传递是完全相同的,而MQTT只是某种程度上是它的“最简单的版本”。

让我们来看一个使用Mosquitto命令行工具的简单示例。使用Mosquitto命令行工具,您可以说:

mosquitto_pub -h localhost -p 1883 -q 1 -t 2020 -m Happy New Year! -V 5 --property publish message-expiry-interval 40

这只是一个最小的示例,但是请注意如何添加消息-期限-间隔。您将其添加为——属性,声明它是一个发布属性。然后添加消息-到期日-间隔关键字和消息的实际寿命(以秒为单位)。请注意,从发布方来看,这仅在执行协议5.0版本时有效(使用- v5)。

很酷的一点是,您的客户仍然可以使用3.1.1版本,并受益于消息过期特性。VerneMQ完全处理了这个问题。一个有状态的3.1.1会话的订阅者,如果在40秒内没有上线,就不会收到我们的"Happy New Year!"消息:

mosquitto_sub -h localhost -p 1883 -u test -P test -t 2020 -q 1 -i SUBSCRIBER -c

注意,虽然MQTT规范是相对精确的,但是目前代理实现者对消息过期的一些小方面的理解可能略有不同。如果具有干净会话和QoS 0的客户端在40秒的窗口中上线,它是否获得应用程序消息?规范中也有一些非常深奥的内容。例如,你也可以为遗嘱信息设置过期时间间隔:

“如果存在,4字节值是将消息的生命周期(以秒为单位),并在服务器发布将消息时作为发布到期时间间隔发送。”

找出一个用例。我们试图务实地实现这些特性,但我们也听取用户和用例的意见。所以,请告诉我们您将如何使用消息过期功能!

Tags: mqtt, Message Expiry, dead lettering

Related Posts:

Leave a Comment