跳到主要内容

队列头阻塞

队列头阻塞(HoL)指的是以下情况:

  • 保证消息正在通过事件代理之间的DMR链接或VPN桥接链接发送,
  • 一个或多个保证端点已满,
  • 一些保证消息无法被交付,因为它们被卡在了目的地是已满端点的消息后面。

当一个端点已满,并且有新消息发布到该端点时,代理只有两个选择。代理可以丢弃该消息,或者它可以拒绝从发布者那里接受新消息。PubSub+代理的默认操作是向消息发布到该端点的发布者发送负面确认(NACKs)。这种默认行为确保事件网格永远不会丢失已发布的消息。

当消息的发布者和消费者在同一代理上时,这种机制非常有效。在这种情况下,唯一受影响的发布者是那些试图向已满端点发送消息的发布者。问题出现在发布者和消费者在不同的代理上,并且消息必须通过代理间链接(DMR链接或VPN桥接)发送时。以下图表说明了这种情况:

img

在上图中,Queue1(订阅了主题a/b/c)因为没有任何连接的客户端来消费队列中的消息而已满。由于消息起源于另一个代理,Broker2知道它不能向发布消息的代理发送NACK,因为那个代理,Broker1,已经向发布应用程序发送了ACK。所以Broker2简单地丢弃了消息。Broker1等待Broker2的ACK超时后,它会重新传递消息。

结果,发布到Queue2上的主题d/e/fQueue3上的主题g/h/i的消息无法被交付,因为它们被卡在了通过代理间链接发送到主题a/b/c的消息后面,或者被队列头阻塞。那个已满的队列阻止了所有其他保证消息通过代理间链接被交付到该消息VPN。

如何防止队列头阻塞

为了防止HoL阻塞,您可以监控您的代理以检测可能发生阻塞的条件,并选择配置设置以减少其发生的可能性。

监控未被服务的保证端点

防止队列头阻塞最重要的工具是监控队列和主题端点的告警事件。如果应用程序没有从端点消费消息(或消费速度不够快),端点就会充满,消息VPN就会被HoL阻塞。Solace选择的端点深度和告警阈值的默认值旨在为您提供足够的时间来解决此问题。您有多少时间反应取决于写入端点的消息大小和消息被传递到端点的速率。

下表显示了您对告警的反应时间,假设代理在创建端点时分配的默认深度和告警阈值(您当然可以调整这些值以更好地满足您的需求)。该表还假设消息大小为1KB,默认队列大小和默认告警阈值。

进入保证端点的速率反应时间(从告警到端点满)
1K msg/sec62.5分钟
30K msg/sec2.08分钟

当代理警告管理员端点即将满时,管理员应该:

  • 联系端点的“所有者”,并与他们合作使消费者应用程序重新上线并从端点消费
  • 如果队列是非独占队列,但提供的流量速率如此之高以至于消费应用程序无法跟上,向队列添加更多的消费者应用程序以进一步分担工作量
  • 如果端点的消费者无法恢复,关闭端点的入站。请注意,此解决方案仅在端点未配置为reject-msg-to-sender-on-discard including-when-shutdown时有效。 此操作导致目的地为该端点的消息被丢弃。

确保消息缓冲区正确大小

在代理上配置足够大的消息缓冲区也非常重要。它必须足够大,以至于一个已满的端点不能使用分配给消息VPN或代理的所有消息缓冲区。Solace建议将每个消息VPN的max-spool-usage属性设置为至少10GB,最好25GB或更多。我们还建议将整个代理的max-spool-usage设置为每个消息VPN的max-spool-usage之和(这对于软件代理尤其重要,软件代理的默认max-spool-usage值非常小,以便它能够在设计师的笔记本电脑和台式电脑上以小占用空间运行)。

有关max-spool-usage默认值的详细信息,请参见最大缓冲使用量。

在端点上选择“丢弃”而不是“阻止发布者”操作

PubSub+事件代理默认为端点选择在永远不会丢失消息的选项上出错。

如果您的应用程序消息有有限的生命周期,那么Solace建议在端点上启用生存时间(TTL),以便从端点未被消费的旧消息自动从该端点中移除。

如果您将端点配置为在TTL到期时将消息发送到死信队列(DMQ),请确保您有一个活跃的消费者从DMQ读取消息。如果代理无法将消息移动到DMQ,代理将丢弃该消息。

您还可以配置端点以丢弃目的地为已满端点的消息,而不是拒绝消息给发布者。这确保了当端点已满时,代理间链接永远不会被HoL阻塞。相反,新的消息目的地为该端点将被丢弃。

使用重放来恢复丢弃的消息

如果包含引起HoL阻塞的端点的消息VPN启用了消息重放,这可能使您更倾向于选择“丢弃”而不是“阻止发布者”操作。消费者重新上线后,您可以使用重放将丢弃的消息传递给消费者。消息重放可以由消费应用程序或代理管理员启动。在这种情况下,代理管理员可能需要启动向经历消息丢弃的端点的重放。

依赖重放来恢复丢弃的消息假设消费者可以在合理的时间内重新上线,以免任何丢弃的消息从重放日志中被移除。重放日志使用与消息缓冲区相同的磁盘存储,因此它没有无限的容量。