微服务架构|无法分配请求的地址

时间:2017-01-07 17:11:43

标签: java apache http apache-httpclient-4.x

我们有一个微服务架构,其中来自公共(移动应用)的单个请求在内部导致对不同服务的4个HTTP调用。

我观察到的另一个副作用是,在重负荷下,我们开始遇到错误"无法分配请求的地址"。

运行>>> import statistics >>> statistics.median([1, 2, 3]) 2 显示大约6万的计数,而通常它会徘徊在3k左右。

似乎我遇到了端口耗尽。我的应用程序是使用Apache HTTP Client用Java编写的。

解决此问题的最佳方法是什么?我想的解决方案很少,但我不确定它是否是正确的方法:

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

有几个原因可能会耗尽您的可用端口。 (为避免混淆,我会将面向用户的服务器称为“应用程序”。):

  1. 如果您只有一个具有一个IP地址的应用程序实例,则从该计算机到四个微服务中的任何一个的最大连接数限制为临时端口数。默认的临时端口范围因操作系统而异,但可以设置为高达65535(所有端口都可用作固定端口,但这非常不寻常)。
  2. 如果您的微服务响应正在发送Connection: close,或者您的应用程序不支持保持活动,则应用程序将在每次请求后关闭TCP连接。当TCP连接关闭时,关闭端进入TIME_WAIT 2xMSL(参见RFC 1122 section 4.2.2.13)。默认MSL再次因OS而异,但频繁的默认值为30秒。这意味着应用程序将无法使用该端口与60秒的同一微服务进行通信。
  3. 如果微服务正在关闭连接(可能是因为应用程序正在发送Connection: close),它们将进入TIME_WAIT,并且最终可能会在微服务端出现端口耗尽。
  4. 端口耗尽的解决方案取决于上述哪种情况发生。这是我会尝试的:

    • 在应用程序和微服务之间启用保持连接,并使用连接池。这将大大减少应用程序和微服务之间的打开和关闭连接数,避免因TIME_WAIT导致端口耗尽。
    • 65k +单个应用程序实例和单个微服务之间的并发连接很多。如果达到此限制,则可能需要增加单个应用程序实例可用于发出请求的IP地址数,可能需要添加虚拟IP地址。您还可以添加应用程序实例并将它们放在负载均衡器后面。
    • 您可以增加微服务可用的IP地址数量,并使用DNS循环等系统来平衡IP地址之间的负载。
    • 您可以在应用程序和/或微服务的OS级别调整MSL,以减少TIME_WAIT中的套接字数量。不过我不推荐这样做;存在潜在的负面影响,几乎在所有情况下,如果这是您问题的唯一解决方案,那么您的应用程序或架构是错误的。

    我建议先使用keep-alives和连接池。