Java:Apache HttpClient中HttpRoute用法的介绍
当使用Apache HttpClient组件时,常常会用到它的连接池组件。典型的代码如下:PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(httpConfig.getMaxPoolTotal());
connectionManager.setDefaultMaxPerRoute(httpConfig.getMaxDefaultPerRoute());
RequestConfig requestConfig = RequestConfig.custom() //
.setConnectTimeout(httpConfig.getConnectTimeout()) //
.setConnectionRequestTimeout(httpConfig.getConnectionRequestTimeout())//
.setSocketTimeout(httpConfig.getSocketTimeout())//
.build();
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create() //
.setConnectionManager(connectionManager) //
.setDefaultRequestConfig(requestConfig) //
.useSystemProperties();
HttpClient httpClient = httpClientBuilder.build();
其中maxTotal表示此连接池的最大连接数,defaultMaxPerRoute表示每路由最大连接数。这里主涉及到route在Apache HttpClient组件中是怎么使用的题目。先分析一下Apache HttpClient的源代码。以下使用的源代码版本4.5.14。
org.apache.http.impl.client.InternalHttpClient
https://i-blog.csdnimg.cn/direct/544200fb818644b6b292602c2977e0e6.png
可以看到这个方法传入的还是HttpHost,也就是哀求地址,但下面就通过determineRoute方法天生了一个HttpRoute,并且后续也是使用HttpRoute。
org.apache.http.impl.conn.DefaultRoutePlanner
https://i-blog.csdnimg.cn/direct/ef1d48345fab4a438f26f9ff8f30eeaa.png
可以看到默认情况下,路由中的地址就是主机地址。
org.apache.http.impl.execchain.MainClientExec
https://i-blog.csdnimg.cn/direct/567418ea9a3644db9322866299086ba8.png
https://i-blog.csdnimg.cn/direct/ce41b61d56774170aa1ec4171e2ae321.png
https://i-blog.csdnimg.cn/direct/40213a8dca3a4242bd80fc160d113455.png
这里也是使用HttpRoute。
org.apache.http.impl.conn.PoolingHttpClientConnectionManager
https://i-blog.csdnimg.cn/direct/d5fb0f234ced4b218f1402761131c04d.png
这里又开始使用HttpHost。
org.apache.http.impl.conn.DefaultHttpClientConnectionOperator
https://i-blog.csdnimg.cn/direct/0e1bce54d83d42089f4554e3d949f734.png
这里会解析hostName,如果通过hostName能解析出多个IP地址,则依次使用这些IP实行创建socket,只要有一个能创建成功,则制止实行。
从上述代码中可以看到,是按路由地址创建连接池的,如果路由地址中的主机地址可以解析成多个IP地址时,只会使用第一个可用的IP地址。
一样平常都是通过域名访问其它服务,而域名一样平常可以解析出多个IP,而域名默认情况下就是路由主机地址,只能为其中一个IP创建连接,且能创建的最大连接数就是defaultMaxPerRoute的值。这样远远达不到maxTotal的值。
当然,有一种办法是直接使用域名解析出的多个IP访问其它服务,这样每个IP就是一个路由,最后创建的总连接数就可以达到maxTotal的值。但这样的最大毛病是域名解析出的IP一样平常是动态的,可能会不光变化,程序中写死IP是非常不灵活的。
那有没有两全其美的办法,既使用域名访问其它服务,又使用域名解析后的IP作为路由创建连接池,使用连接数创建到最大值。办法是有的,只要实现一个RoutePlanner就行。
public class TestRoutePlanner implements RoutePlanner {
private final Random random = new Random();
public HttpRoute determineRoute(HttpHost host, HttpRequest reqt, HttpContext ctx) {
InetAddress[] addrs = InetAddress.getAllByName(host.getHostnName());
int idx = random.mextInt(addrs.length);
String hostAddr = addrsgetHostAddress();
HttpHost newHost = new HttpHost(hostAddr, host.getPort(), host.getSchemeName());
return new HttpRoute(newHost, null, false);
}
} 然后将TestRoutePlanner添加到HttpClient中。
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create() //
.setConnectionManager(connectionManager) //
.setDefaultRequestConfig(requestConfig) //
.setRoutePlanner(new TestRoutePlanner())//
.useSystemProperties(); 上述TestRoutePlanner写的比力简单,性能也不太好,只是不演示功能而已,现实使用时还需要进一步改造。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]