httpclient发送get请求阻塞?
堆栈信息
某个线程被一个任务一直占用,查看堆栈信息发现是在使用httpclient发送get请求时阻塞了,具体堆栈信息如上,求教
贴上堆栈中打印类的相关代码:
httpclientpool(自己写的一个httpclient连接池)
public class HttpClientPool
{
private static Logger logger = LoggerFactory.getLogger(HttpClientPool.class);
/**
* 站点与HttpClient映射,key:Site,value:ProxyModel->CloseableHttpClient
*/
private static Map<String, ConcurrentHashMap<String, CloseableHttpClient>> SITE_HTTP_CLIENT_MAP = new ConcurrentHashMap<String, ConcurrentHashMap<String, CloseableHttpClient>>();
/**
* 站点与Http链接管理器映射
*/
private static Map<String, ConcurrentHashMap<String, PoolingHttpClientConnectionManager>> SITE_HTTP_CONN_MGR_MAP = new ConcurrentHashMap<String, ConcurrentHashMap<String, PoolingHttpClientConnectionManager>>();
public static final String PROXY_ALL_KEY = "ALL";
/**
* 移除proxy
* @param proxy
*/
public static void removeProxy(Proxy proxy)
{
Collection<ConcurrentHashMap<String, CloseableHttpClient>> proxyClients = SITE_HTTP_CLIENT_MAP.values();
if (null != proxyClients && !proxyClients.isEmpty())
{
for (ConcurrentHashMap<String, CloseableHttpClient> proxyClient : proxyClients)
{
CloseableHttpClient client = proxyClient.get(proxy.getKey());
if (null != client)
{
try
{
client.close();
proxyClient.remove(proxy.getKey());
}
catch (IOException e)
{
logger.warn("HttpClientPool removeProxy:" + proxy.getKey() + "fail!", e);
}
}
}
}
}
/**
* 删除某个站点 HttpClient
* @param site
*/
public static void destroy(Site site)
{
logger.info("start to clear Spider:" + site.getSiteDomain() + " HttpClientPool...");
Map<String, CloseableHttpClient> proxyClients = SITE_HTTP_CLIENT_MAP.get(site.getSiteDomain());
if (null != proxyClients)
{
Collection<CloseableHttpClient> clients = proxyClients.values();
for (CloseableHttpClient client : clients)
{
try
{
client.close();
}
catch (IOException e)
{
logger.warn("close " + site.getSiteDomain() + " HttpClient error", e);
}
}
SITE_HTTP_CLIENT_MAP.remove(site.getSiteDomain());
}
ConcurrentHashMap<String, PoolingHttpClientConnectionManager> proxyCMs = SITE_HTTP_CONN_MGR_MAP.get(site.getSiteDomain());
if (null != proxyCMs)
{
Collection<PoolingHttpClientConnectionManager> cms = proxyCMs.values();
for (PoolingHttpClientConnectionManager cm : cms)
{
try
{
cm.close();
}
catch (Exception e)
{
logger.warn("close " + site.getSiteDomain() + " HttpClientMgr error", e);
}
}
SITE_HTTP_CONN_MGR_MAP.remove(site.getSiteDomain());
}
logger.info("clear Spider:" + site.getSiteDomain() + " HttpClientPool success!");
}
public static CloseableHttpClient getClient(Site site, Proxy proxy)
{
String proxyKey = PROXY_ALL_KEY;
if (null != proxy)
{
proxyKey = proxy.getKey();
}
Map<String, CloseableHttpClient> proxyClients = SITE_HTTP_CLIENT_MAP.get(site.getSiteDomain());
if (null == proxyClients)
{
return generateClient(site, proxy);
}
else
{
if (proxyClients.containsKey(proxyKey))
{
return proxyClients.get(proxyKey);
}
else
{
return generateClient(site, proxy);
}
}
}
private static synchronized CloseableHttpClient generateClient(Site site, Proxy proxy)
{
String proxyKey = PROXY_ALL_KEY;
if (null != proxy)
{
proxyKey = proxy.getKey();
}
ConcurrentHashMap<String, CloseableHttpClient> proxyClients = SITE_HTTP_CLIENT_MAP.get(site.getSiteDomain());
if (null != proxyClients)
{
if (proxyClients.containsKey(proxyKey))
{
return proxyClients.get(proxyKey);
}
}
else
{
proxyClients = new ConcurrentHashMap<String, CloseableHttpClient>();
}
PoolingHttpClientConnectionManager cm = null;
ConcurrentHashMap<String, PoolingHttpClientConnectionManager> proxyCMs = SITE_HTTP_CONN_MGR_MAP.get(site.getSiteDomain());
if (null != proxyCMs)
{
if (proxyCMs.containsKey(proxyKey))
{
cm = proxyCMs.get(proxyKey);
}
}
else
{
proxyCMs = new ConcurrentHashMap<>();
SITE_HTTP_CONN_MGR_MAP.put(site.getSiteDomain(), proxyCMs);
}
if (null == cm)
{
try
{
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (arg0, arg1) -> true).build();
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", sslSocketFactory).build();
cm = new PoolingHttpClientConnectionManager(reg);
cm.setDefaultMaxPerRoute(site.getConcurCon());
cm.setMaxTotal(site.getConcurCon());
proxyCMs.put(proxyKey, cm);
}
catch (Exception e)
{
logger.warn("",e);
}
}
// 请求重试处理
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandlerImpl(site.getRetryTimes());
HttpClientBuilder clientBuilder = HttpClients.custom().setConnectionManager(cm).setRetryHandler(retryHandler).setKeepAliveStrategy(new HttpClientKeepAliveStrategy());
if (site != null && site.getUserAgent() != null)
{
clientBuilder.setUserAgent(site.getUserAgent());
}
else
{
clientBuilder.setUserAgent("");
}
if (site.useGzip())
{
clientBuilder.addInterceptorFirst(new HttpRequestInterceptor()
{
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException
{
if (!request.containsHeader("Accept-Encoding"))
{
request.addHeader("Accept-Encoding", "gzip");
}
}
});
}
RequestConfig.Builder reqConfigBuilder = RequestConfig.custom().setConnectionRequestTimeout(site.getTimeoutMs()).setConnectTimeout(site.getTimeoutMs()).setSocketTimeout(site.getTimeoutMs())
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).setRedirectsEnabled(false);
if (site.useProxy() && null != proxy)
{
HttpHost host = new HttpHost(proxy.getHost(), proxy.getPort());
if (!CommonUtil.isEmptyStr(proxy.getAuthName()) && ProxyType.DEFAULT.code() == proxy.getProxyType())
{
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(proxy.getAuthName(), proxy.getAuthPwd()));//用户名和密码
clientBuilder.setDefaultCredentialsProvider(credsProvider);
}
else
{
reqConfigBuilder.setProxy(host);
}
}
RequestConfig reqConfig = reqConfigBuilder.build();
clientBuilder.setDefaultRequestConfig(reqConfig);
CloseableHttpClient client = clientBuilder.build();
proxyClients.put(proxyKey, client);
SITE_HTTP_CLIENT_MAP.put(site.getSiteDomain(), proxyClients);
return client;
}
/**
* 获取所有的连接池管理器
*
* @return
*/
public static Collection<PoolingHttpClientConnectionManager> getAllConnMgrs()
{
List<PoolingHttpClientConnectionManager> cms = new ArrayList<PoolingHttpClientConnectionManager>();
Collection<ConcurrentHashMap<String, PoolingHttpClientConnectionManager>> all = SITE_HTTP_CONN_MGR_MAP.values();
for (ConcurrentHashMap<String, PoolingHttpClientConnectionManager> siteCMs : all)
{
Collection<PoolingHttpClientConnectionManager> proxyCMs = siteCMs.values();
cms.addAll(proxyCMs);
}
return cms;
}
}
HttpCustomConnect:
public class HttpCustomConnect
{
private static final Logger logger = LoggerFactory.getLogger(HttpCustomConnect.class);
private Request req;
public enum Method
{
GET, POST;
}
public static HttpCustomConnect connect(String url)
{
return new HttpCustomConnect().url(url);
}
public HttpCustomConnect()
{
req = new Request();
}
public HttpCustomConnect httpClient(CloseableHttpClient client)
{
req.httpClient(client);
return this;
}
public HttpCustomConnect url(String url)
{
req.url(url);
return this;
}
public HttpCustomConnect data(String name, String value)
{
req.data(name, value);
return this;
}
public HttpCustomConnect data(Map<String, String> data)
{
if (null == data)
{
return this;
}
for (Map.Entry<String, String> entity : data.entrySet())
{
req.data(entity.getKey(), entity.getValue());
}
return this;
}
public HttpCustomConnect get()
{
req.method(Method.GET);
return this;
}
public HttpCustomConnect post()
{
req.method(Method.POST);
return this;
}
public Method getMethod()
{
return req.method;
}
public HttpCustomConnect headers(Map<String, String> headers)
{
if (null == headers)
{
return this;
}
for (Map.Entry<String, String> entity : headers.entrySet())
{
req.header(entity.getKey(), entity.getValue());
}
return this;
}
public HttpCustomConnect header(String name, String value)
{
req.header(name, value);
return this;
}
public HttpCustomConnect cookie(String name, String value)
{
req.cookie(name, value);
return this;
}
public HttpCustomConnect cookie(Map<String, String> cookies)
{
if (null == cookies)
{
return this;
}
for (Map.Entry<String, String> entity : cookies.entrySet())
{
req.cookie(entity.getKey(), entity.getValue());
}
return this;
}
private static class Request
{
private CloseableHttpClient client;
private String url;
private Map<String, String> data;
private Map<String, String> headers;
private Map<String, String> cookies;
private Method method = Method.GET;
public void httpClient(CloseableHttpClient client)
{
this.client = client;
}
public void url(String url)
{
this.url = url;
}
public void data(String name, String value)
{
if (null == data)
{
data = new HashMap<String, String>();
}
this.data.put(name, value);
}
public void method(Method method)
{
this.method = method;
}
public Method getMethod()
{
return this.method;
}
public void header(String name, String value)
{
if (null == this.headers)
{
headers = new HashMap<String, String>();
}
this.headers.put(name, value);
}
public void cookie(String name, String value)
{
if (null == cookies)
{
cookies = new HashMap<String, String>();
}
this.cookies.put(name, value);
}
public CloseableHttpClient getClient()
{
return client;
}
public String getUrl() throws IOException
{
StringBuilder urlStr = new StringBuilder();
urlStr.append(this.url);
if (Method.POST.equals(method) || (Method.GET.equals(method) && null == data))
{
return urlStr.toString();
}
urlStr.append("?");
for (Map.Entry<String, String> entry : data.entrySet())
{
urlStr.append(URLEncoder.encode(CommonUtil.getString(entry.getKey()), "UTF-8"));
urlStr.append("=");
urlStr.append(URLEncoder.encode(CommonUtil.getString(entry.getValue()), "UTF-8"));
urlStr.append("&");
}
return urlStr.toString();
}
public Map<String, String> getData()
{
return data;
}
public Map<String, String> getHeaders()
{
Map<String, String> header = new HashMap<String, String>();
header.put("connection", "Keep-Alive");
header.put("Accept-Encoding", "gzip");
if (null != headers)
{
header.putAll(headers);
}
if (null != cookies)
{
header.putAll(getCookies());
}
return header;
}
public Map<String, String> getCookies()
{
Map<String, String> cookie = new HashMap<String, String>();
StringBuilder sb = new StringBuilder();
if (null == cookies)
{
return null;
}
for (Map.Entry<String, String> entry : cookies.entrySet())
{
sb.append(entry.getKey());
sb.append("=");
sb.append(entry.getValue());
sb.append("; ");
}
cookie.put("cookie", sb.toString());
return cookie;
}
}
public static class Response
{
private Map<String, String> cookies;
private String body;
public Map<String, String> cookies()
{
return cookies;
}
public String cookie(String name)
{
return cookies.get(name);
}
public String body()
{
return body;
}
public void setCookies(Map<String, String> cookies)
{
this.cookies = cookies;
}
public void setBody(String body)
{
this.body = body;
}
}
public Response execute() throws IOException, HttpException
{
CloseableHttpClient client = (null == req.getClient() ? HttpClients.createDefault() : req.getClient());
String url = req.getUrl();
Map<String, String> header = req.getHeaders();
Map<String, String> data = req.getData();
if (req.getMethod().equals(Method.GET))
{
return sendGetAndGetResponse(client, url, header);
}
else
{
return sendAndPostResponse(client, url, data, header);
}
}
/**
* 发送Get请求
* @param client
* @param url
* @param headers
* @return
* @throws HttpException
*/
public static Response sendGetAndGetResponse(CloseableHttpClient client, String url, Map<String, String> headers) throws HttpException
{
Response custResponse = new Response();
if (null == client)
{
logger.error("send http get request error,HttpClient is null");
return null;
}
HttpEntity entity = null;
CloseableHttpResponse response = null;
HttpGet request = null;
try
{
request = new HttpGet(url);
if (null != headers)
{
for (String key : headers.keySet())
{
request.setHeader(key, headers.get(key));
}
}
response = client.execute(request, HttpClientContext.create());
int status = response.getStatusLine().getStatusCode();
if (status < 200 || status >= 400)
{
throw new HttpException(status, status + ":" + response.getStatusLine().getReasonPhrase());
}
custResponse.setBody(EntityUtils.toString(response.getEntity(), "utf-8"));
custResponse.setCookies(getCookieFromGetHttpResponse(response));
return custResponse;
}
catch (HttpException e)
{
throw e;
}
catch (Exception e)
{
throw new HttpException(ResponseCode.FAIL.getCode(), e.getMessage());
}
finally
{
if (null != entity)
{
try
{
EntityUtils.consume(entity);
}
catch (IOException e)
{
e.printStackTrace();
}
}
if (null != response)
{
try
{
response.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
if (null != request)
{
request.releaseConnection();
}
}
}
/**
* 发送Post请求
* @param client
* @param url
* @param params
* @param headers
* @return
* @throws HttpException
*/
public static Response sendAndPostResponse(CloseableHttpClient client, String url, Map<String, ? extends Object> params, Map<String, String> headers) throws HttpException
{
Response custResponse = new Response();
HttpPost request = new HttpPost(url);
HttpEntity responseEntity = null;
CloseableHttpResponse response = null;
try
{
if (null != headers)
{
for (String key : headers.keySet())
{
request.setHeader(key, headers.get(key));
}
}
if (null != params && !params.isEmpty())
{
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
Set<String> keySet = params.keySet();
for (String key : keySet)
{
nvps.add(new BasicNameValuePair(key, CommonUtil.getString(params.get(key))));
}
request.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
}
response = client.execute(request, HttpClientContext.create());
int status = response.getStatusLine().getStatusCode();
if (status < 200 || status >= 400)
{
throw new HttpException(status, status + ":" + response.getStatusLine().getReasonPhrase());
}
custResponse.setBody(EntityUtils.toString(response.getEntity(), "UTF-8"));
custResponse.setCookies(getCookieFromGetHttpResponse(response));
return custResponse;
}
catch (HttpException e)
{
throw e;
}
catch (Exception e)
{
e.printStackTrace();
throw new HttpException(ResponseCode.FAIL.getCode(), e.getMessage());
}
finally
{
if (null != responseEntity)
{
try
{
EntityUtils.consume(responseEntity);
}
catch (IOException e)
{
e.printStackTrace();
}
}
if (null != response)
{
try
{
response.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
if (null != request)
{
request.releaseConnection();
}
}
}
/**
* 从response获取cookies
* @param response
* @return
*/
public static Map<String, String> getCookieFromGetHttpResponse(CloseableHttpResponse response)
{
Map<String, String> cookiesMap = null;
Header[] cookies = response.getAllHeaders();
if (null == cookies || cookies.length == 0)
{
return cookiesMap;
}
cookiesMap = new HashMap<>();
for (Header cookie : cookies)
{
if (!"Set-Cookie".equalsIgnoreCase(cookie.getName()))
{
continue;
}
String value = cookie.getValue().split(";")[0].trim();
if (value.split("=").length >= 2)
{
int index = value.indexOf("=");
cookiesMap.put(value.substring(0, index), value.substring(index + 1));
}
}
return cookiesMap;
}
/**
* 下载文件
* @param url
* @param filePath
* @return
*/
public static Response DownLoad(String url, String dirPath, String fileName) throws Exception
{
return downLoad(null, url, null, null, dirPath, fileName);
}
/**
* 下载文件
* @param client
* @param url
* @param params
* @param headers
* @param filePath
* @return
*/
public static Response downLoad(CloseableHttpClient client, String url, Map<String, ? extends Object> params, Map<String, String> headers, String dirPath, String fileName) throws Exception
{
Response custResponse = new Response();
if (null == client)
{
client = HttpClients.createDefault();
}
CloseableHttpResponse response = null;
FileOutputStream fos = null;
HttpGet request = null;
try
{
request = new HttpGet(url);
if (null != headers)
{
for (String key : headers.keySet())
{
request.setHeader(key, headers.get(key));
}
}
response = client.execute(request, HttpClientContext.create());
int status = response.getStatusLine().getStatusCode();
if (status != 200)
{
throw new HttpException(status, status + ":" + response.getStatusLine().getReasonPhrase());
}
File dir = new File(dirPath);
if (!dir.isDirectory())
{
dir.mkdirs();
}
File file = new File(dir, fileName);
if (file == null || !file.exists())
{
file.createNewFile();
}
fos = new FileOutputStream(file);
response.getEntity().writeTo(fos);
custResponse.setCookies(getCookieFromGetHttpResponse(response));
return custResponse;
}
finally
{
if (null != response)
{
try
{
response.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
if (null != request)
{
request.releaseConnection();
}
if (null != fos)
{
try
{
fos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
把你的代码贴出来。
初步判断
你如果使用了lock,就是lock导致的锁问题
。问题已经解决,
参考:https://issues.apache.org/jir...