从负载均衡器中删除后很长时间服务器接收应用程序请求

Server receiving webRequests long after removed from LoadBalancer

我在大约 7 年前支持的系统上遇到了以下问题。我们从未追根究底,注意力转移到其他问题上。我最近想起了它,想知道是否有人知道发生了什么事。但是,唉,我会在细节上有点短。对不起。


设置

我有一个位于负载平衡器后面的网络服务器场。服务器正在托管一个系统,该系统将从客户端接收 HTTP 请求(XML 和/或 SOAP),然后为每个启动向第 3 方供应商发出一堆进一步的 HTTP 请求,等待供应商的请求响应、处理和组合结果并响应客户的请求。

考虑保险比较,但作为企业对企业 XML 服务。

整个处理过程需要 5 秒,从接收初始客户端请求到他们发回对原始 HTTP 请求的响应,服务器将并行处理 10 或 100 秒的请求(即在任何给定的情况下)点,给定的网络服务器会有许多客户端请求已经进入并记录,但尚未得到响应。)

我们有详细的日志记录,记录请求的接收情况,包括原始 IP 和正在处理请求的服务器,并记录发送响应的时间。

所有客户端请求都发送到一个 IP 地址(好吧,URL),这是负载均衡器的地址,然后负载均衡器会将请求转发到网络服务器,这些服务器无法单独访问互联网(他们没有 public IP 地址)。

我们的负载平衡器允许我们停止轮换单独的网络服务器以进行维护。 当我们这样做时,我们可以查看数据库日志,看到新的请求停止进来,现有的请求逐渐完成,直到现在有未完成的请求并且服务器空闲。


问题

我们发现,有时,当我们停止轮换服务器时……它不会完全停止接收请求。您可能会看到大量请求突然停止进来,但它仍会收到少量新请求(我不知道……也许是正常负载的 0.1%,也许更少?)。我认为我们离开它的最长时间可能是... 10 分钟?

值得注意的是,我们意识到所有这些请求都来自一个 client/IP 地址(我不记得是哪个地址了)。 我忘记了其他(仍在轮换中的)网络服务器是否仍在接收来自该客户端的请求,但我 认为 它们是?

如果我们重新启动网络服务器,则在重新启动后不会有更多的请求进来。

Web 堆栈是 Windows、IIS、ASP.NET;即使在当时也很老派。所有服务器均单独拥有和配置。


发生了什么事?

我们含糊地挥了挥手,断言客户端与我们的集成是 "holding an HTTP tunnel open and sending multiple requests through it",而不是单独发送每个请求,因此即使在 LB 停止向该服务器发送新请求后,该隧道仍在维护。但那是废话,因为我们从来不需要真正了解发生了什么,所以我们忽略了它并继续我们的生活:)

但我仍然想知道我们看到了什么,是否有人可以根据该描述做出诊断。

We vaguely waved our hands and asserted that the client's integration with us was "holding an HTTP tunnel open and sending multiple requests through it", rather than sending each request separately, and thus was maintaining that tunnel even after the LB stopped sending new requests to that server.

听起来不错。

通常情况下,LB 会拒绝与已删除服务器的新连接,但会允许打开的连接继续存在,直到它们自然关闭。这被称为 "connection draining" 或 "graceful shutdown"。

如果您的某个客户端启用了 HTTP keepalive,并且长时间保持 TCP 连接打开并通过它发送 HTTP 请求,它就会出现您描述的症状。

大多数 LB 都会有一个配置旋钮,用于指定在此 "connection draining" 时间内强制关闭连接之前等待连接关闭的时间。如果这对您来说是个问题,您可以在此处设置超时以避免这种情况。

客户端的 HTTP 连接处理行为在很大程度上由客户端自行决定。也许您的大多数客户端都属于一种类型(例如,Web 浏览器)并且不会保持打开一个连接 10 分钟,但也许有一个客户端不同(例如,程序化 HTTP API 客户端)?

在此处进一步阅读关于 AWS 负载均衡器的 "connection draining"(具体细节因负载均衡供应商而异):https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/config-conn-drain.html

进一步阅读有关 HTTP keep alive 的信息:https://en.wikipedia.org/wiki/HTTP_persistent_connection