Apache Http客户端和负载均衡器

时间:2015-03-21 16:03:50

标签: java httpclient load-balancing apache-httpclient-4.x

花了几个小时阅读Http客户端文档和源代码后,我决定在这里寻求帮助。

我有一个负载平衡器服务器使用循环算法,有点像这样

+---> RESTServer1 client --> load balancer +---> RESTServer2 +---> RESTServer3

我们的客户正在使用HttpClient将请求定向到我们的负载均衡器服务器,后者又将请求循环到相应的RESTServer。

现在,Apache HttpClient默认创建a pool of connections(默认情况下每条路由2条)。默认情况下,此连接是持久连接,因为我使用的是Http v1.1,而我的服务器正在发送Connection:Keep-Alive标头。

因此,问题在于,由于HttpClient创建了这种持久连接,因此这些连接不再受平衡器级别的循环算法的影响。他们每次总是打同一台服务器。

这会产生两个问题:

  1. 我可以看到,有时一个或多个平衡服务器的流量过载,而其他服务器中有一个或多个闲置;和
  2. 即使我将我的一台REST服务器从平衡器中取出,它仍然会在持久连接处于活动状态时接收请求。
  3. 当然这不是预期的行为。

    我想我可以在我的回复中强制使用Connection: close标头,或者我可以在没有连接池或NoConnectionReuseStrategy的情况下运行HttpClient。但HttpClient的the documentation指出,使用池的想法是通过避免每次都打开套接字并进行所有TPC握手和相关的东西来提高性能。因此,我必须得出结论,使用连接池有利于我的应用程序的性能。

    所以我的问题是,有没有办法在路上使用与负载均衡器的持久连接,还是我被迫在这种情况下使用非持久连接?

    我想要重用连接所带来的性能,但我希望它们能够正确地进行负载平衡。有关如何使用Apache Http Client配置此场景的任何想法,如果可能的话?

2 个答案:

答案 0 :(得分:4)

您的问题可能与您的负载均衡器配置和负载均衡的风格有关。有几种方法:

  1. HTTP重定向
  2. LB充当反向代理
  3. 纯数据包转发
  4. 在方案1和3中,您没有机会使用持久连接。如果您的负载均衡器就像一个反向代理,那么可能有一种方法可以通过平衡实现持久连接。 "哑"平衡器,如SMTP或LDAP,选择每个TCP连接的目标,而不是基于请求。

    例如,带有balancer模块的Apache HTTPd服务器(请参阅http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html)可以将每个请求(甚至是持久连接)分派给不同的服务器。

    另外检查一下,您没有收到可能是会话持久性的平衡器cookie,因此原因不是持久连接而是平衡器cookie。

    HTH,马克

答案 1 :(得分:1)

+1来@ mp911de回答

通过将持久连接的总生存时间限制在某个短时间段(例如15秒),也可以使方案1和3工作得相当好。通过这种方式,连接可以存活足够长的时间以便在活动期间重复使用,并且足够短以在相对不活动期间消失。