httpclient发送get请求阻塞?

发布于 2022-09-05 04:51:42 字数 22252 浏览 11 评论 0

图片描述

堆栈信息

某个线程被一个任务一直占用,查看堆栈信息发现是在使用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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你是年少的欢喜 2022-09-12 04:51:42

把你的代码贴出来。
初步判断你如果使用了lock,就是lock导致的锁问题

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文