Apache Http客户端和负载均衡器

5
在花费几个小时阅读 Http Client 文档和源代码后,我决定应该在这里寻求帮助。
我有一个使用轮询算法的负载均衡器服务器,类似于:
+---> RESTServer1 客户端 --> 负载均衡器 +---> RESTServer2 +---> RESTServer3
我们的客户端使用 HttpClient 将请求发送到我们的负载均衡器服务器,然后轮询将请求发送到相应的 RESTServer。
现在,Apache HttpClient 默认创建一组连接(默认情况下每个路由 2 个连接)。由于我使用的是 Http v1.1 并且我的服务器正在发出 Connection: Keep-Alive 标头,因此这些连接默认为持久连接。
所以,问题是由于 HttpClient 创建这些持久连接,因此这些连接不再受到负载均衡器级别的轮询算法的影响。它们每次都会命中同一台服务器。
这会产生两个问题:
  1. 我发现有时候负载均衡服务器中的一个或多个会因为流量过大而超载,而其他服务器中的一个或多个却处于空闲状态;
  2. 即使我将其中一个REST服务器从平衡器中取出,只要持久连接仍然存在,它仍会收到请求。

显然这不是预期行为。

我想我可以在响应中强制使用Connection: close头,或者我可以在没有连接池或使用NoConnectionReuseStrategy的情况下运行HttpClient。但是HttpClient的文档指出,使用连接池的想法是通过避免每次打开套接字并执行所有TPC握手和相关工作来提高性能。因此,我必须得出结论,使用连接池对我的应用程序的性能有益。

所以我的问题是,在这种方式下是否有一种使用持久连接的方法或者我被迫在这种情况下使用非持久连接?

我希望能够利用重用连接所带来的性能优势,但同时也想让它们得到适当的负载均衡。如果可能的话,你对如何在Apache Http客户端中配置这种情况有什么想法吗?


我相信你可以在负载均衡器中进行配置。那是实现所需行为的正确地方,需要动手操作。 - fps
2个回答

5
您的问题可能更与负载均衡器配置和负载均衡风格有关。有几种方式:
  1. HTTP重定向
  2. LB作为反向代理
  3. 纯数据包转发
在情况1和3中,您没有机会使用持久连接。如果您的负载均衡器充当反向代理,则可能有一种方法可以实现带平衡的持久连接。像SMTP或LDAP这样的“愚蠢”负载均衡器会根据TCP连接而不是请求基础选择目标。
例如,具有balancer模块的Apache HTTPd服务器(请参见http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html)可以将每个请求(甚至在持久连接上)分派到不同的服务器。
还要检查您是否收到了一个可能是会话持久的负载均衡器cookie,以便原因不是持久连接而是负载均衡器cookie。
希望对您有所帮助,马克

这是一个相当不错的线索。我们正在使用F5 LB,我刚刚发现了这个链接,它似乎描述了你在回答中提到的内容。 - Edwin Dalorzo
你是指“数据包转发”吗? - OrangeDog
是的,我修好了。谢谢你的提示。 - mp911de

2

+1 对 @mp911de 的回答

如果将持久连接的总生存时间限制在较短的时间段内(例如15秒),则可以使方案1和3合理地运行。这样,在活动期间,连接可以保持足够长的时间以便重复使用,在相对不活跃的时期,则可以足够短以便消失。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接