在花费几个小时阅读 Http Client 文档和源代码后,我决定应该在这里寻求帮助。
我有一个使用轮询算法的负载均衡器服务器,类似于:
+---> RESTServer1 客户端 --> 负载均衡器 +---> RESTServer2 +---> RESTServer3
我们的客户端使用 HttpClient 将请求发送到我们的负载均衡器服务器,然后轮询将请求发送到相应的 RESTServer。
现在,Apache HttpClient 默认创建一组连接(默认情况下每个路由 2 个连接)。由于我使用的是 Http v1.1 并且我的服务器正在发出 Connection: Keep-Alive 标头,因此这些连接默认为持久连接。
所以,问题是由于 HttpClient 创建这些持久连接,因此这些连接不再受到负载均衡器级别的轮询算法的影响。它们每次都会命中同一台服务器。
这会产生两个问题:
我有一个使用轮询算法的负载均衡器服务器,类似于:
+---> RESTServer1 客户端 --> 负载均衡器 +---> RESTServer2 +---> RESTServer3
我们的客户端使用 HttpClient 将请求发送到我们的负载均衡器服务器,然后轮询将请求发送到相应的 RESTServer。
现在,Apache HttpClient 默认创建一组连接(默认情况下每个路由 2 个连接)。由于我使用的是 Http v1.1 并且我的服务器正在发出 Connection: Keep-Alive 标头,因此这些连接默认为持久连接。
所以,问题是由于 HttpClient 创建这些持久连接,因此这些连接不再受到负载均衡器级别的轮询算法的影响。它们每次都会命中同一台服务器。
这会产生两个问题:
- 我发现有时候负载均衡服务器中的一个或多个会因为流量过大而超载,而其他服务器中的一个或多个却处于空闲状态;
- 即使我将其中一个REST服务器从平衡器中取出,只要持久连接仍然存在,它仍会收到请求。
显然这不是预期行为。
我想我可以在响应中强制使用Connection: close
头,或者我可以在没有连接池或使用NoConnectionReuseStrategy的情况下运行HttpClient。但是HttpClient的文档指出,使用连接池的想法是通过避免每次打开套接字并执行所有TPC握手和相关工作来提高性能。因此,我必须得出结论,使用连接池对我的应用程序的性能有益。
所以我的问题是,在这种方式下是否有一种使用持久连接的方法或者我被迫在这种情况下使用非持久连接?
我希望能够利用重用连接所带来的性能优势,但同时也想让它们得到适当的负载均衡。如果可能的话,你对如何在Apache Http客户端中配置这种情况有什么想法吗?