Apache Http 客户端和负载平衡器
Apache Http Client and Load Balancers
在花了几个小时阅读 Http Client 文档和源代码后,我决定一定要在这里寻求帮助。
我有一个负载均衡器服务器,它使用 round-robin 有点像这样的算法
+---> RESTServer1
client --> load balancer +---> RESTServer2
+---> RESTServer3
我们的客户端正在使用 HttpClient 将请求定向到我们的负载平衡器服务器,后者又 round-robin 将请求发送到相应的 RESTServer。
现在,Apache HttpClient 默认创建 a pool of connections(默认每个路由 2 个)。默认情况下,此连接是持久连接,因为我使用的是 Http v1.1 并且我的服务器正在发出连接:Keep-Alive headers.
因此,问题在于,由于 HttpClient 创建了此持久连接,因此这些连接不再受制于平衡器级别的 round-robing 算法。他们总是每次都访问同一个服务器。
这会产生两个问题:
- 我看到有时一台或多台平衡服务器流量过载,而一台或多台其他服务器空闲;和
- 即使我将我的一个 REST 服务器从平衡器中取出,它仍然会在持久连接处于活动状态时接收请求。
这绝对不是预期的行为。
我想我可以在我的回复中强制使用 Connection: close
header,或者我可以 运行 HttpClient 没有连接池或带有 NoConnectionReuseStrategy. But the documentation 的 HttpClient 声明使用池背后的想法是通过避免每次都打开套接字并执行所有 TPC 握手和相关操作来提高性能。所以,我不得不得出结论,连接池的使用对我的应用程序的性能是有益的。
所以我的问题是,有没有一种方法可以使用带有 load-balancer 的持久连接,或者我是否被迫在这种情况下使用 non-persistent 连接?
我想要重用连接带来的性能,但我希望它们正确 load-balanced。如果可能的话,我对如何使用 Apache Http Client 配置此场景有什么想法吗?
您的问题可能与您的负载均衡器配置和负载均衡方式有关。有几种方式:
- HTTP 重定向
- LB 作为反向代理
- 纯数据包转发
在场景 1 和场景 3 中,您没有机会使用持久连接。如果您的负载平衡器充当反向代理,则可能有一种方法可以通过平衡实现持久连接。 "Dumb" 平衡器,如 SMTP 或 LDAP 按 TCP 连接选择目标,而不是基于请求。
例如,带有平衡器模块的 Apache HTTPd 服务器(参见 http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html)可以将每个请求(即使在持久连接上)分派到不同的服务器。
同时检查您没有收到可能是会话持久性的平衡器 cookie,因此原因不是持久连接而是平衡器 cookie。
HTH,马克
+1 给@mp911de 回答
还可以通过将持久连接的总生存时间限制在某个较短的时间段(比如 15 秒)来使场景 1 和场景 3 工作得相当好。这样,连接将存在足够长的时间以在 activity 期间重新使用,并且足够短以在相对 inactivity.
期间消失
在花了几个小时阅读 Http Client 文档和源代码后,我决定一定要在这里寻求帮助。
我有一个负载均衡器服务器,它使用 round-robin 有点像这样的算法
+---> RESTServer1
client --> load balancer +---> RESTServer2
+---> RESTServer3
我们的客户端正在使用 HttpClient 将请求定向到我们的负载平衡器服务器,后者又 round-robin 将请求发送到相应的 RESTServer。
现在,Apache HttpClient 默认创建 a pool of connections(默认每个路由 2 个)。默认情况下,此连接是持久连接,因为我使用的是 Http v1.1 并且我的服务器正在发出连接:Keep-Alive headers.
因此,问题在于,由于 HttpClient 创建了此持久连接,因此这些连接不再受制于平衡器级别的 round-robing 算法。他们总是每次都访问同一个服务器。
这会产生两个问题:
- 我看到有时一台或多台平衡服务器流量过载,而一台或多台其他服务器空闲;和
- 即使我将我的一个 REST 服务器从平衡器中取出,它仍然会在持久连接处于活动状态时接收请求。
这绝对不是预期的行为。
我想我可以在我的回复中强制使用 Connection: close
header,或者我可以 运行 HttpClient 没有连接池或带有 NoConnectionReuseStrategy. But the documentation 的 HttpClient 声明使用池背后的想法是通过避免每次都打开套接字并执行所有 TPC 握手和相关操作来提高性能。所以,我不得不得出结论,连接池的使用对我的应用程序的性能是有益的。
所以我的问题是,有没有一种方法可以使用带有 load-balancer 的持久连接,或者我是否被迫在这种情况下使用 non-persistent 连接?
我想要重用连接带来的性能,但我希望它们正确 load-balanced。如果可能的话,我对如何使用 Apache Http Client 配置此场景有什么想法吗?
您的问题可能与您的负载均衡器配置和负载均衡方式有关。有几种方式:
- HTTP 重定向
- LB 作为反向代理
- 纯数据包转发
在场景 1 和场景 3 中,您没有机会使用持久连接。如果您的负载平衡器充当反向代理,则可能有一种方法可以通过平衡实现持久连接。 "Dumb" 平衡器,如 SMTP 或 LDAP 按 TCP 连接选择目标,而不是基于请求。
例如,带有平衡器模块的 Apache HTTPd 服务器(参见 http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html)可以将每个请求(即使在持久连接上)分派到不同的服务器。
同时检查您没有收到可能是会话持久性的平衡器 cookie,因此原因不是持久连接而是平衡器 cookie。
HTH,马克
+1 给@mp911de 回答
还可以通过将持久连接的总生存时间限制在某个较短的时间段(比如 15 秒)来使场景 1 和场景 3 工作得相当好。这样,连接将存在足够长的时间以在 activity 期间重新使用,并且足够短以在相对 inactivity.
期间消失