public
static
synchronized
HttpClient getHttpClient()
{
if
(
null
== customerHttpClient)
{
HttpParams params =
new
BasicHttpParams();
/* 设置一些基本参数 */
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, CHARSET);
HttpProtocolParams.setUseExpectContinue(params,
true
);
HttpProtocolParams.setUserAgent(params,
"Mozilla/5.0(Linux;U;Android 2.2.1;en-us;Nexus One Build.FRG83) "
+
"AppleWebKit/553.1(KHTML,like Gecko) Version/4.0 Mobile Safari/533.1"
);
// 超时设置
// 从连接池中取连接的超时时间
ConnManagerParams.setTimeout(params,
5000
);
// 连接超时
HttpConnectionParams.setConnectionTimeout(params,
10000
);
// 请求超时
HttpConnectionParams.setSoTimeout(params,
10000
);
// 设置我们的HttpClient支持HTTP和HTTPS两种模式
SchemeRegistry schReg =
new
SchemeRegistry();
schReg.register(
new
Scheme(
"http"
, PlainSocketFactory.getSocketFactory(),
80
));
schReg.register(
new
Scheme(
"https"
, SSLSocketFactory.getSocketFactory(),
443
));
// 使用线程安全的连接管理来创建HttpClient
ClientConnectionManager conMgr =
new
ThreadSafeClientConnManager(params, schReg);
customerHttpClient =
new
DefaultHttpClient(conMgr, params);
}
return
customerHttpClient;
}
HttpClient的3种超时说明
ConnManagerParams.setTimeout(params, 5000);
/*连接超时 */
HttpConnectionParams.setConnectionTimeout(params, 10000);
/*请求超时 */
HttpConnectionParams.setSoTimeout(params, 10000);
第一行设置ConnectionPoolTimeout:这定义了从ConnectionManager管理的连接池中取出连接的超时时间,此处设置为5秒。
第二行设置ConnectionTimeout: 这定义了通过网络与服务器建立连接的超时时间。Httpclient包中通过一个异步线程去创建与服务器的socket连接,这就是该socket连接的超时时间,此处设置为10秒。
第三行设置SocketTimeout: 这定义了Socket读数据的超时时间,即从服务器获取响应数据需要等待的时间,此处设置为10秒。
以上3种超时分别会抛出ConnectionPoolTimeoutException,ConnectionTimeoutException与SocketTimeoutException异常。
最大连接数、获取连接的最大等待时间、读取超时时间 这些配置应该比较容易理解,一般的连接池都会有这些配置,比较特别的是 每个路由(route)最大连接数 。
什么是一个route?
这里route的概念可以理解为 运行环境机器 到 目标机器的一条线路。举例来说,我们使用HttpClient的实现来分别请求 www.baidu.com 的资源和 www.bing.com 的资源那么他就会产生两个route。
这里为什么要特别提到route最大连接数这个参数呢,因为这个参数的默认值为2,如果 不设置这个参数值默认情况下对于同一个目标机器的最大并发连接只有2个!这意味着如果你正在执行一个针对某一台目标机器的抓取任务的时候,哪怕你设置连接 池的最大连接数为200,但是实际上还是只有2个连接在工作,其他剩余的198个连接都在等待,都是为别的目标机器服务的。
上面的代码中并没有设置每个路由的最大连接数,如果需要设置,只需要在第18行插入如下代码:
// MAX_ROUTE_CONNECTIONS为要设置的每个路由最大连接数
ConnPerRouteBean connPerRoute =
new
ConnPerRouteBean(MAX_ROUTE_CONNECTIONS);
ConnManagerParams.setMaxConnectionsPerRoute(httpParams,connPerRoute);