httpclient连接池配置

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.5.2</version>

</dependency>

package com.iscas.datasong.lib.util;

import com.iscas.datasong.lib.common.DataSongException;
import com.iscas.datasong.lib.common.Status;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;


public class BaseHttpClientPoolUtil {
    /*最大连接数,应该放在配置文件内*/
    private int maxTotal = 800;
    /*每个路由的最大连接数*/
    private int maxPerRoute = 200;
    /**
     * 向服务端请求超时时间设置(单位:毫秒)
     */
    private static int SERVER_REQUEST_TIME_OUT = 2000;
    /**
     * 服务端响应超时时间设置(单位:毫秒)
     */
    private static int SERVER_RESPONSE_TIME_OUT = 2000;

    /*从连接池获取连接的超时时间*/
    private static int CONNECTION_REQUEST_TIME_OUT = 2000;
    /*重试次数*/
    private static int retry = 3;
    //    /*是否关闭socket缓冲*/
//    private boolean tcpNoDelay = false;
//    /*关闭socket后,是否可立即重用端口*/
//    private boolean soReuseAddress = true;
//    /*接收数据等待超时时间毫秒*/
//    private int soTimeout = 500;
//    /*socket最大等待关闭连接时间秒*/
//    private int soLinger = 60;
    private static volatile PoolingHttpClientConnectionManager pollManager = null;

    public BaseHttpClientPoolUtil() throws NoSuchAlgorithmException {
        init();
    }

    private void init() throws NoSuchAlgorithmException {
        if (pollManager == null) {
            synchronized (BaseHttpClientPoolUtil.class){
                if(pollManager == null){
                    LayeredConnectionSocketFactory sslsf = null;
                    sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
                    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                            .register("https", sslsf)
                            .register("http", new PlainConnectionSocketFactory())
                            .build();
                    pollManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
                    pollManager.setMaxTotal(maxTotal);
                    pollManager.setDefaultMaxPerRoute(maxPerRoute);

                    //某个host的路由数配置,覆盖default,暂时不配置
                    //pollManager.setMaxPerRoute(new HttpRoute(new HttpHost("some host", 80)), 150);

//        //socket配置
//        SocketConfig socketConfig = SocketConfig.custom()
//                .setTcpNoDelay(tcpNoDelay)     //是否立即发送数据,设置为true会关闭Socket缓冲,默认为false
//                .setSoReuseAddress(soReuseAddress) //是否可以在一个进程关闭Socket后,即使它还没有释放端口,其它进程还可以立即重用端口
//                .setSoTimeout(soTimeout)       //接收数据的等待超时时间,单位ms
//                .setSoLinger(soLinger)         //关闭Socket时,要么发送完所有数据,要么等待60s后,就关闭连接,此时socket.close()是阻塞的
//                .setSoKeepAlive(true)    //开启监视TCP连接是否有效
//                .build();
//        pollManager.setDefaultSocketConfig(socketConfig);
                }

            }
        }
    }

    public CloseableHttpClient getHttpClient(int SERVER_REQUEST_TIME_OUT, int SERVER_RESPONSE_TIME_OUT, int CONNECTION_REQUEST_TIME_OUT) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(SERVER_REQUEST_TIME_OUT).setConnectTimeout(SERVER_RESPONSE_TIME_OUT).build();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(pollManager)
                .setRetryHandler(getHttpRequestRetryHandler())
                .build();
        return httpClient;
    }

    public RequestConfig getDefaultRequestConfig() {
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(SERVER_REQUEST_TIME_OUT)
                .setConnectTimeout(SERVER_RESPONSE_TIME_OUT)
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIME_OUT)
                .build();
        return requestConfig;
    }


    public HttpRequestRetryHandler getHttpRequestRetryHandler(){
        HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {

            public boolean retryRequest(
                    IOException exception,
                    int executionCount,
                    HttpContext context) {
                if (executionCount >= retry) {
                    // 如果已经重试了5次,就放弃
                    return false;
                }
                if (exception instanceof InterruptedIOException) {
                    // 超时
                    return false;
                }
                if (exception instanceof UnknownHostException) {
                    // 目标服务器不可达
                    return false;
                }
                if (exception instanceof ConnectTimeoutException) {
                    // 连接被拒绝
                    return false;
                }
                if (exception instanceof SSLException) {
                    // ssl握手异常
                    return false;
                }
                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                if (idempotent) {
                    // 如果请求是幂等的,就再次尝试
                    return true;
                }
                return false;
            }

        };
        return myRetryHandler;
    }

    public CloseableHttpClient getHttpClient() {
        RequestConfig requestConfig = getDefaultRequestConfig();
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig)
                .setConnectionManager(pollManager)
                .setRetryHandler(getHttpRequestRetryHandler())
                .build();
        return httpClient;
    }

    public String doGet(String url) throws DataSongException {
        if (DataSongStringUtils.isEmpty(url)) {
            throw new DataSongException(Status.PARAM_ERROR, "param can not be null");
        }

        //    url = validateUrl(url);

        CloseableHttpResponse response = null;
        String body = null;
        try {
            HttpGet get = new HttpGet(url);

            get.addHeader("Content-type", "application/json; charset=utf-8");
            get.setHeader("Accept", "application/json");

            response = getHttpClient().execute(get);

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                body = EntityUtils.toString(response.getEntity());
            } else {
                throw new DataSongException(Status.SERVER_ERROR, String.format("error code [%s]", statusCode));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return body;
    }
    /**
     * 执行post方法
     * @param url
     * @param parameter
     * @return
     */
    public String doPost(String url, String parameter) throws DataSongException {
        if(DataSongStringUtils.isEmpty(url)){
            throw new DataSongException(Status.PARAM_ERROR, "url can not be null");
        }

        //    url = validateUrl(url);

        String body = null;
        CloseableHttpResponse response = null;
        try {

            HttpPost httpPost = new HttpPost(url);

            httpPost.addHeader("Content-type", "application/json; charset=utf-8");
            httpPost.setHeader("Accept", "application/json");
            if(!DataSongStringUtils.isEmpty(parameter)) {
                httpPost.setEntity(new StringEntity(parameter, Charset.forName("UTF-8")));
            }

            response = getHttpClient().execute(httpPost);

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                body = EntityUtils.toString(response.getEntity());
            } else {
                throw new DataSongException(Status.SERVER_ERROR, String.format("error code []",statusCode));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(null!=response){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return body;
    }

    public String doPut(String url, String parameter) throws DataSongException {
//    if(DataSongStringUtils.isEmpty(parameter) || DataSongStringUtils.isEmpty(url)){
//       throw new DataSongException(Status.PARAM_ERROR, "param can not be null");
//    }

        //    url = validateUrl(url);

        String body = null;
        CloseableHttpResponse response = null;
        try {
            HttpPut httpPost = new HttpPut(url);

            httpPost.addHeader("Content-type", "application/json; charset=utf-8");
            httpPost.setHeader("Accept", "application/json");
            if(null!=parameter){
                httpPost.setEntity(new StringEntity(parameter, Charset.forName("UTF-8")));
            }
            response = getHttpClient().execute(httpPost);

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                body = EntityUtils.toString(response.getEntity());
            } else {
                throw new DataSongException(Status.SERVER_ERROR, String.format("%s ,error code [%s]",response.getStatusLine().getReasonPhrase(),statusCode));
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(null!=response){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return body;
    }

    public String doDelete(String url) throws DataSongException {
        if(DataSongStringUtils.isEmpty(url)){
            throw new DataSongException(Status.PARAM_ERROR, "param can not be null");
        }

        //    url = validateUrl(url);

        String body = null;
        CloseableHttpResponse response = null;
        try {
            HttpDelete delete = new HttpDelete(url);

            delete.addHeader("Content-type", "application/json; charset=utf-8");
            delete.setHeader("Accept", "application/json");

            response = getHttpClient().execute(delete);

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                // Read the response body
                body = EntityUtils.toString(response.getEntity());
            } else {
                throw new DataSongException(Status.SERVER_ERROR, String.format("error code []",statusCode));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(null!=response){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return body;
    }

    protected String validateUrl(String url){
        if(url.contains("?")){
            url = url.replace("?","%26");
        }

        if(url.contains("&")){
            url = url.replace("&","%3F");
        }

        if(url.contains("|")){
            url = url.replace("|","%124");
        }

        if(url.contains("=")){
            url = url.replace("=","%3D");
        }

        if(url.contains("#")){
            url = url.replace("#","%23");
        }

        if(url.contains("/")){
            url = url.replace("/","%2F");
        }

        if(url.contains("+")){
            url = url.replace("+","%2B");
        }

        if(url.contains("%")){
            url = url.replace("%","%25");
        }

        if(url.contains(" ")){
            url = url.replace(" ","%20");
        }

        return url;
    }
}

猜你喜欢

转载自blog.csdn.net/u011943534/article/details/79524647