AWS 经典 LB 更改 IPs/dropping 连接导致 RabbitMQ 上的消息丢失
AWS classic LB changing IPs/dropping connections results in lost messages on RabbitMQ
我 运行 一个具有 3 个节点的 rabbit HA 集群和一个经典的 AWS 负载均衡器 (LB) 在它们前面。有两个app,一个发布,一个通过LB消费。
当发布者应用程序开始发送 300 万条消息时,短时间后其连接将进入流量控制状态。发布完成后,在发布者应用日志中我可以看到所有 300 万条消息都已发送。另一方面,在消费者应用程序日志中,我只能看到 500K - 1M 条消息(在 运行 之间变化),这意味着大量消息丢失了。
所以发生的事情是,在 运行 中间,经典 LB 决定更改其 IP 地址或断开连接,从而丢失大量消息(有关详细信息,请参阅我的更新)。
如果我跳过 LB 并直接访问节点,在应用程序端进行负载平衡,则不会出现此问题。当然在这种情况下我失去了ELB的所有好处。
我的问题是:
- 为什么 LB 会更改 IP 地址并断开连接,这是否与来自发布者或流量控制状态的高消息率有关?
- 如何配置LB,才不会出现这个问题?
更新:
这是我对正在发生的事情的理解:
我使用 AMQP 0-9-1 并在没有“publish confirms”的情况下发布,因此消息一经传输就被视为已发送。此外,rabbitmq 节点上的连接是在 LB 和节点之间,而不是 Publisher 应用程序和节点之间。
在通信进入Flow Control之前,消息立即从LB传递到一个节点
然后LB和一个节点的连接进入Flow Control,Publisher App连接没有被阻塞,所以继续以同样的速率发布。这会导致消息堆积在 LB 上。
然后LB决定更换IP或出于任何原因断开连接并创建一个新的连接,导致所有堆积的消息丢失。从 RabbitMQ 日志中可以清楚地看到这一点:
=警告报告==== 2018 年 1 月 6 日::10:35:50 ===
关闭 AMQP 连接 <0.30342.375> (10.1.1.250:29564 -> 10.1.1.223:5672):
客户端意外关闭 TCP 连接
=信息报告==== 2018 年 1 月 6 日::10:35:51 ===
接受 AMQP 连接 <0.29123.375> (10.1.1.22:1886 -> 10.1.1.223:5672)
ELB 在根据流量进行扩展时会更改其地址。新节点出现,出现在 DNS 中,然后旧节点最终可能会消失,也可能会保持在线。
It increases capacity by utilizing either larger resources (resources with higher performance characteristics) or more individual resources. The Elastic Load Balancing service will update the Domain Name System (DNS) record of the load balancer when it scales so that the new resources have their respective IP addresses registered in DNS. The DNS record that is created includes a Time-to-Live (TTL) setting of 60 seconds, with the expectation that clients will re-lookup the DNS at least every 60 seconds. (emphasis added)
— from “Best Practices in Evaluating Elastic Load Balancing”
您可能会在该“最佳实践”指南中找到更多有用的信息,包括在 AWS 支持的帮助下预热平衡器的概念,以及如何以平衡器扩展的方式增加测试流量可以跟上。
经典 ELB 的行为是自动的,用户无法配置。
但听起来好像您的队列有配置问题,因为它似乎应该更能应对掉线的情况。
另请注意,AWS Network Load Balancer 不会更改其 IP 地址,也不需要像 ELB 那样通过替换资源来扩展,因为与 ELB 不同,它似乎 运行在隐藏的实例上——它是网络基础设施的一部分,或者至少看起来是这样。这可能是一个可行的选择。
解决方案是使用AWS 网络 LB。网络 LB 将在 Publisher App 和 rabbitmq 节点之间创建连接。因此,如果连接被阻止或断开,发布者将意识到这一点并采取相应行动。我对 3M 消息进行了 运行 相同的测试,并且没有丢失单个消息。
在 AWS 文档中,有一行解释了行为:
Preserve source IP address Network Load Balancer preserves the client side source IP allowing the back-end to see the IP address of
the client. This can then be used by applications for further
processing.
我 运行 一个具有 3 个节点的 rabbit HA 集群和一个经典的 AWS 负载均衡器 (LB) 在它们前面。有两个app,一个发布,一个通过LB消费。
所以发生的事情是,在 运行 中间,经典 LB 决定更改其 IP 地址或断开连接,从而丢失大量消息(有关详细信息,请参阅我的更新)。
如果我跳过 LB 并直接访问节点,在应用程序端进行负载平衡,则不会出现此问题。当然在这种情况下我失去了ELB的所有好处。
我的问题是:
- 为什么 LB 会更改 IP 地址并断开连接,这是否与来自发布者或流量控制状态的高消息率有关?
- 如何配置LB,才不会出现这个问题?
更新:
这是我对正在发生的事情的理解: 我使用 AMQP 0-9-1 并在没有“publish confirms”的情况下发布,因此消息一经传输就被视为已发送。此外,rabbitmq 节点上的连接是在 LB 和节点之间,而不是 Publisher 应用程序和节点之间。
在通信进入Flow Control之前,消息立即从LB传递到一个节点
然后LB和一个节点的连接进入Flow Control,Publisher App连接没有被阻塞,所以继续以同样的速率发布。这会导致消息堆积在 LB 上。
然后LB决定更换IP或出于任何原因断开连接并创建一个新的连接,导致所有堆积的消息丢失。从 RabbitMQ 日志中可以清楚地看到这一点:
=警告报告==== 2018 年 1 月 6 日::10:35:50 === 关闭 AMQP 连接 <0.30342.375> (10.1.1.250:29564 -> 10.1.1.223:5672): 客户端意外关闭 TCP 连接
=信息报告==== 2018 年 1 月 6 日::10:35:51 === 接受 AMQP 连接 <0.29123.375> (10.1.1.22:1886 -> 10.1.1.223:5672)
ELB 在根据流量进行扩展时会更改其地址。新节点出现,出现在 DNS 中,然后旧节点最终可能会消失,也可能会保持在线。
It increases capacity by utilizing either larger resources (resources with higher performance characteristics) or more individual resources. The Elastic Load Balancing service will update the Domain Name System (DNS) record of the load balancer when it scales so that the new resources have their respective IP addresses registered in DNS. The DNS record that is created includes a Time-to-Live (TTL) setting of 60 seconds, with the expectation that clients will re-lookup the DNS at least every 60 seconds. (emphasis added)
— from “Best Practices in Evaluating Elastic Load Balancing”
您可能会在该“最佳实践”指南中找到更多有用的信息,包括在 AWS 支持的帮助下预热平衡器的概念,以及如何以平衡器扩展的方式增加测试流量可以跟上。
经典 ELB 的行为是自动的,用户无法配置。
但听起来好像您的队列有配置问题,因为它似乎应该更能应对掉线的情况。
另请注意,AWS Network Load Balancer 不会更改其 IP 地址,也不需要像 ELB 那样通过替换资源来扩展,因为与 ELB 不同,它似乎 运行在隐藏的实例上——它是网络基础设施的一部分,或者至少看起来是这样。这可能是一个可行的选择。
解决方案是使用AWS 网络 LB。网络 LB 将在 Publisher App 和 rabbitmq 节点之间创建连接。因此,如果连接被阻止或断开,发布者将意识到这一点并采取相应行动。我对 3M 消息进行了 运行 相同的测试,并且没有丢失单个消息。
在 AWS 文档中,有一行解释了行为:
Preserve source IP address Network Load Balancer preserves the client side source IP allowing the back-end to see the IP address of the client. This can then be used by applications for further processing.