apache httpClientCreateFactory模版

HttpClientFactory

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

public class HttpClientFactory {

    public static HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
        @Override
        public boolean retryRequest(IOException exception,
                                    int executionCount, HttpContext context) {
            if (executionCount >= 5) {
                return false;
            }
            if (exception instanceof NoHttpResponseException) {
                return true;
            }
            if (exception instanceof InterruptedIOException) {
                return false;
            }
            if (exception instanceof UnknownHostException) {
                return false;
            }
            if (exception instanceof ConnectTimeoutException) {
                return false;
            }
            HttpClientContext clientContext = HttpClientContext
                    .adapt(context);
            HttpRequest request = clientContext.getRequest();

            return !(request instanceof HttpEntityEnclosingRequest);
        }
    };
    private static final int MAX_TOTAL_CONNECTIONS = 1000;
    private static final int MAX_CONNECTIONS_PER_ROUTE = 600;
    private static final int CONNECTION_TIMEOUT_MS = 10000;
    private static final int SOCKET_TIMEOUT_MS = 30000;
    private static ConnectionKeepAliveStrategy connectionKeepAliveStrategy;

    public static ClientInstance create(HttpHost proxy) {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        connectionManager.setDefaultMaxPerRoute(MAX_CONNECTIONS_PER_ROUTE);

        ConnectionKeepAliveStrategy strategy;
        if (connectionKeepAliveStrategy != null) {
            strategy = connectionKeepAliveStrategy;
        } else {
            strategy = getConnectionKeepAliveStrategy();
        }

        HttpClient httpClient;
        httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setKeepAliveStrategy(strategy)
                .setRetryHandler(httpRequestRetryHandler)
                .setDefaultRequestConfig(createRequestConfig())
                .setProxy(proxy)
                .build();

        Thread daemonThread = new Thread(new IdleConnectionMonitorThread(connectionManager));
        daemonThread.setDaemon(true);
        daemonThread.start();

        return new ClientInstance(httpClient, daemonThread);
    }

    public static ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() {
        return new ConnectionKeepAliveStrategy() {
            @Override
            public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                HeaderElementIterator it = new BasicHeaderElementIterator
                        (response.headerIterator(HTTP.CONN_KEEP_ALIVE));
                while (it.hasNext()) {
                    HeaderElement he = it.nextElement();
                    String param = he.getName();
                    String value = he.getValue();
                    if (value != null && param.equalsIgnoreCase
                            ("timeout")) {
                        return Long.parseLong(value) * 1000;
                    }
                }
                return 60 * 1000;//如果没有约定,则默认定义时长为60s
            }
        };
    }

    public static void setConnectionKeepAliveStrategy(ConnectionKeepAliveStrategy connectionKeepAliveStrategy) {
        HttpClientFactory.connectionKeepAliveStrategy = connectionKeepAliveStrategy;
    }

    private static RequestConfig createRequestConfig() {
        return RequestConfig.custom()
                .setConnectTimeout(CONNECTION_TIMEOUT_MS)           //连接超时时间
                .setSocketTimeout(SOCKET_TIMEOUT_MS)                //socket超时时间
                .setConnectionRequestTimeout(CONNECTION_TIMEOUT_MS) //从连接池获取连接的超时时间
                .setExpectContinueEnabled(false)                    //禁用"Expect: 100-continue"头
                .setStaleConnectionCheckEnabled(true)               //开启stale connection检查
                //.setProxy(new HttpHost("proxy.example.com", 8080))  //设置代理服务器地址和端口号,这个参数可以根据实际情况进行设置。如果不需要使用代理服务器,可以将这一行代码删除或注释掉。
                .build();
    }

    @Getter
    @AllArgsConstructor
    public static class ClientInstance{
        private HttpClient httpClient;
        private Thread daemonThread;
    }
}

IdleConnectionMonitorThread

import org.apache.http.conn.HttpClientConnectionManager;

import java.util.concurrent.TimeUnit;

public class IdleConnectionMonitorThread extends Thread {

    private final HttpClientConnectionManager connMgr;
    private volatile boolean shutdown;

    public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
        super();
        this.connMgr = connMgr;
    }

    @Override
    public void run() {
        try {
            while (!shutdown) {
                synchronized (this) {
                    wait(5000);
                    // Close expired connections
                    connMgr.closeExpiredConnections();
                    // Optionally, close connections
                    // that have been idle longer than 30 sec
                    connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
                }
            }
        } catch (InterruptedException ex) {
            // terminate
        }
    }

    public void shutdown() {
        shutdown = true;
        synchronized (this) {
            notifyAll();
        }
    }
}

posted @ 2023-02-24 17:54  MorningBell  阅读(27)  评论(0编辑  收藏  举报