HttpClient 连接池配置和使用

如果每次都重新创建一个新的HttpClient对象的话,当并发上来时,容易出现异常或连接失败,超时。这里可以使用HttpClient的连接池配置,减少HttpClient创建的数量,减少资源开销。

package com.mygame.common.utils;

 

import java.io.IOException;

import java.security.KeyManagementException;

import java.security.KeyStoreException;

import java.security.NoSuchAlgorithmException;

import org.apache.http.Header;

import org.apache.http.HttpStatus;

import org.apache.http.client.config.RequestConfig;

import org.apache.http.client.methods.CloseableHttpResponse;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.config.Registry;

import org.apache.http.config.RegistryBuilder;

import org.apache.http.conn.socket.ConnectionSocketFactory;

import org.apache.http.conn.socket.PlainConnectionSocketFactory;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;

import org.apache.http.conn.ssl.TrustSelfSignedStrategy;

import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

import org.apache.http.ssl.SSLContextBuilder;

import org.apache.http.util.EntityUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

 

public class GameHttpClient {

    private static Logger logger = LoggerFactory.getLogger(GameHttpClient.class);

    // 池化管理

    private static PoolingHttpClientConnectionManager poolConnManager = null;

 

    private static CloseableHttpClient httpClient;// 它是线程安全的,所有的线程都可以使用它一起发送http请求

    static {

        try {

            System.out.println("初始化HttpClientTest~~~开始");

            SSLContextBuilder builder = new SSLContextBuilder();

            builder.loadTrustMaterial(nullnew TrustSelfSignedStrategy());

            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());

            // 配置同时支持 HTTP 和 HTPPS

            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslsf).build();

            // 初始化连接管理器

            poolConnManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);

            poolConnManager.setMaxTotal(640);// 同时最多连接数

            // 设置最大路由

            poolConnManager.setDefaultMaxPerRoute(320);

            // 此处解释下MaxtTotal和DefaultMaxPerRoute的区别:

            // 1、MaxtTotal是整个池子的大小;

            // 2、DefaultMaxPerRoute是根据连接到的主机对MaxTotal的一个细分;比如:

            // MaxtTotal=400 DefaultMaxPerRoute=200

            // 而我只连接到http://www.abc.com时,到这个主机的并发最多只有200;而不是400;

            // 而我连接到http://www.bac.com 和

            // http://www.ccd.com时,到每个主机的并发最多只有200;即加起来是400(但不能超过400);所以起作用的设置是DefaultMaxPerRoute

            // 初始化httpClient

            httpClient = getConnection();

 

            System.out.println("初始化HttpClientTest~~~结束");

        catch (NoSuchAlgorithmException e) {

            e.printStackTrace();

        catch (KeyStoreException e) {

            e.printStackTrace();

        catch (KeyManagementException e) {

            e.printStackTrace();

        }

    }

 

    public static CloseableHttpClient getConnection() {

        RequestConfig config = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(5000).build();

        CloseableHttpClient httpClient = HttpClients.custom()

                // 设置连接池管理

                .setConnectionManager(poolConnManager)

                .setDefaultRequestConfig(config)

                // 设置重试次数

                .setRetryHandler(new DefaultHttpRequestRetryHandler(2false)).build();

        return httpClient;

    }

     

    public static String httpGet(String url) {

        HttpGet httpGet = new HttpGet(url);

        CloseableHttpResponse response = null;

         

        try {

            response = httpClient.execute(httpGet);

            String result = EntityUtils.toString(response.getEntity());

            int code = response.getStatusLine().getStatusCode();

            if (code == HttpStatus.SC_OK) {

                return result;

            else {

                logger.error("请求{}返回错误码:{},{}", url, code,result);

                return null;

            }

        catch (IOException e) {

            logger.error("http请求异常,{}",url,e);

        finally {

            try {

                if (response != null)

                    response.close();

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        return null;

    }

    public static String post(String uri, Object params, Header... heads) {

        HttpPost httpPost = new HttpPost(uri);

        CloseableHttpResponse response = null;

        try {

            StringEntity paramEntity = new StringEntity(JSON.toJSONString(params));

            paramEntity.setContentEncoding("UTF-8");

            paramEntity.setContentType("application/json");

            httpPost.setEntity(paramEntity);

            if (heads != null) {

                httpPost.setHeaders(heads);

            }

             response = httpClient.execute(httpPost);

            int code = response.getStatusLine().getStatusCode();

            String result = EntityUtils.toString(response.getEntity());

            if (code == HttpStatus.SC_OK) {

                return result;

            else {

                logger.error("请求{}返回错误码:{},请求参数:{},{}", uri, code, params,result);

                return null;

            }

        catch (IOException e) {

            logger.error("收集服务配置http请求异常", e);

        finally {

            try {

               if(response != null) {

                   response.close();

               }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        return null;

    }

 

}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值