花了几个小时阅读Http客户端文档和源代码后,我决定在这里寻求帮助。
我有一个负载平衡器服务器使用循环算法,有点像这样
+---> RESTServer1
client --> load balancer +---> RESTServer2
+---> RESTServer3
我们的客户正在使用HttpClient将请求定向到我们的负载均衡器服务器,后者又将请求循环到相应的RESTServer。
现在,Apache HttpClient默认创建a pool of connections(默认情况下每条路由2条)。默认情况下,此连接是持久连接,因为我使用的是Http v1.1,而我的服务器正在发送Connection:Keep-Alive标头。
因此,问题在于,由于HttpClient创建了这种持久连接,因此这些连接不再受平衡器级别的循环算法的影响。他们每次总是打同一台服务器。
这会产生两个问题:
当然这不是预期的行为。
我想我可以在我的回复中强制使用Connection: close
标头,或者我可以在没有连接池或NoConnectionReuseStrategy的情况下运行HttpClient。但HttpClient的the documentation指出,使用池的想法是通过避免每次都打开套接字并进行所有TPC握手和相关的东西来提高性能。因此,我必须得出结论,使用连接池有利于我的应用程序的性能。
所以我的问题是,有没有办法在路上使用与负载均衡器的持久连接,还是我被迫在这种情况下使用非持久连接?
我想要重用连接所带来的性能,但我希望它们能够正确地进行负载平衡。有关如何使用Apache Http Client配置此场景的任何想法,如果可能的话?
答案 0 :(得分: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工作得相当好。通过这种方式,连接可以存活足够长的时间以便在活动期间重复使用,并且足够短以在相对不活动期间消失。