Compartir a través de

Azure 服务总线 - 消息到期时间(生存时间)

消息中的有效负载,或者由消息传递给接收方的命令或查询,几乎总是附带了某种形式的应用程序级过期截止时间。 此截止时间过后,便不再传送内容,或不再执行请求的操作。

对于经常在应用程序或应用程序部件部分运行轮次的上下文中使用队列与主题的开发和测试环境,还需要对滞留的测试消息自动进行垃圾回收,使下一轮测试运行能够从新启动。

注意

如果尚不熟悉服务总线概念,请参阅服务总线概念服务总线队列、主题和订阅

可以通过设置 time-to-live 系统属性(指定相对持续时间)来控制任何一条消息的过期时间。 在实体中将消息排队后,过期时间即成为一个绝对时刻。 此时,expires-at-utc 属性取值为 enqueued-time-utctime-to-live。 + 如果没有任何客户端在主动侦听,则不强制实施中转消息的生存时间 (TTL) 设置。

注意

代理可能不会立即删除已过期的消息。 代理可能会根据在消息过期时实体是否处于活动状态,选择使这些消息延迟过期。 因此,客户在使用消息过期时可能会观察到不正确的消息计数,甚至可能会在速览操作期间看到这些消息。 但是,在接收消息时,将不包括过期的消息。

在 expires-at-utc 时刻过后,消息将变为不可检索。 到期并不会影响当前锁定进行传递的消息。 仍会正常处理这些消息。 如果锁已过期或者消息被丢弃,则过期时间立即生效。 消息被锁定时,应用程序可以拥有已过期的消息。 应用程序是要继续处理还是选择丢弃消息,则由实施者决定。

如果 TTL 极低(毫秒级或秒级),则消息在接收方应用程序接收它之前就可能已过期。 请考虑适用于你的应用程序的最高 TTL。

注意

对于计划的消息,可以指定需要消息在队列中出现供检索所花的时间。 消息发送到服务总线的时间与消息排入队列的时间不同。 消息过期时间取决于排队的时间,而非消息发送到服务总线的时间。 因此,expires-at-utc 仍然是 enqueued time + time-to-live。

例如,如果将 ScheduledEnqueueTimeUtcUtcNow 设置为 5 分钟,将 TimeToLive 设置为 10 分钟,则消息将在从现在开始的 5 + 10 = 15 分钟后过期。 5 分钟后,消息在队列中出现,此时,10 分钟计数器开始计时。

实体级过期时间

发送到队列或主题的所有消息均受在实体级别设置的默认到期时间的限制。 也可以在门户中创建消息期间设置默认到期时间,并在以后调整。 默认过期时间是针对发送到未显式设置生存时间的实体的所有消息使用的。 默认过期时间还充当生存时间值的上限。 生存时间过期时间长于默认值的消息在排队之前,会以无提示方式调整为默认消息生存时间值。

expires-at-utc 是按设计进行的。 如果未设置消息 TTL,并且仅设置实体 TTL,则 expires-at-utc 是一个计算值,不会在 Peek 路径中计算,而是在 Receive/Peeklock 路径中计算。 如果消息具有 TTL,则在发送和存储消息时会计算此 expires-at-utc。 因此,在这种情况下,Peek 将返回正确的 expires-at-utc 值

注意

  • 如果没有另外指定,则中转消息的默认生存时间值为有符号 64 位整数的最大可能值。
  • 对于消息传送实体(队列和主题),服务总线标准层和高级层的默认到期时间也是有符号 64 位整数的最大可能值。 对于基本层,默认(也是最大)到期时间为 14 天 。
  • 如果主题指定的 TTL 比订阅指定的 TTL 小,则应用主题 TTL。

可以选择将过期的消息移动到死信队列中。 可以通过编程方式或使用 Azure 门户来配置此设置。 如果保持禁用该选项,将会丢弃已过期的消息。 可以通过评估由中转站存储在用户属性部分中的 dead-letter reason 属性,将已移到死信队列的已过期消息与其他死信消息区分开来。

如果消息被锁定以防止过期,并且在实体上设置了相应的标志,则锁被丢弃或过期时,会将该消息移到死信队列。 但是,如果已成功解决该消息,因而认为应用程序已成功处理该消息,则不会移动该消息,尽管它在名义上已过期。 有关消息锁和处置的详细信息,请参阅消息传输、锁和处置

生存时间与过期时自动(和根据事务)加入死信队列的组合是一种极为有用的工具,让我们确信在到达期限时,能够检索在期限范围内提供给一个或一组处理程序的作业进行处理。

例如,假设某个网站需要在规模受限的后端上可靠执行作业,并且偶尔会遇到流量高峰,或者需要受到隔离,以防止该后端在某段时间遇到可用性问题。 在一般情况下,所提交用户数据的服务器端处理程序会将信息推入队列,随后在回复队列中接收确认已成功处理事务的回复。 如果出现流量高峰并且后端处理程序无法及时处理其积压工作项,则已过期的作业会返回到死信队列中。 可以告知交互用户请求的操作所花费的时间比平时稍长,然后可将请求放到不同队列的处理路径,并通过电子邮件将其中的最终处理结果发送给用户。

临时实体

可将服务总线队列、主题和订阅创建为临时实体,在指定的时间段内未使用这些实体时,系统会自动将其删除。

在动态创建实体并且由于测试或调试运行中断,导致用后不会清理实体的开发和测试方案中,自动清理功能十分有用。 当应用程序创建动态实体(例如回复队列)用于在 Web 服务器进程或者生存期相对较短的对象(对象实例消失时难以可靠清理这些实体)中接收响应时,此功能也很有用。

此功能是使用实体上的“空闲时自动删除”属性启用的。 此属性设置为自动删除某个实体之前,该实体必须处于空闲(未使用)状态的持续时间。 此属性的最小值为 5 分钟。

重要

在命名空间或更高级别上,将 Azure 资源管理器锁定级别设置为 CanNotDelete 不会阻止删除具有 AutoDeleteOnIdle 的实体。 如果不希望删除实体,将 AutoDeleteOnIdle 属性设置为 DataTime.MaxValue

空闲

下面是被视为实体(队列、主题和订阅)空闲的一些情况:

实体 被视为空闲的情况
队列
  • 无发送
  • 无接收
  • 无队列更新
  • 无计划的消息
  • 无浏览/速览
主题
  • 无发送
  • 无主题更新
  • 无计划的消息
  • 没有对主题的订阅执行任何操作(见下一行)
订阅
  • 无接收
  • 无订阅更新
  • 无添加到订阅的新规则
  • 无浏览/速览

重要

如果在队列或订阅上设置了自动转发,则相当于让接收方在队列或订阅上进行接收,并且它们不会处于空闲状态。

SDK

后续步骤

若要了解有关服务总线消息传送的详细信息,请参阅以下文章: