zoukankan      html  css  js  c++  java
  • HttpClient 连接池配置和使用

    在游戏项目开发中,经常会向其它的服务发送一些Http请求,获取一些数据或验证。比如充值,SDK验证等。如果每次都重新创建一个新的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(null, new 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(2, false)).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;
        }
    
    }
    

     


     QQ交流群:66728073,197321069

  • 相关阅读:
    Re: 求助:5道算法题
    AutoComplete的字典建立和单词查找算法实现
    求教大牛!关于后缀树
    Qt OpenGL教程
    调试宏
    if结合errorlevel使用:判断一个DOS命令执行成功与否
    写给自己,关于对纯技术的追求,以及为了金钱与前途的技术追求
    <转>我对菜鸟成长的看法
    看完电影有感。。。。。
    <转>标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast
  • 原文地址:https://www.cnblogs.com/wgslucky/p/11270038.html
Copyright © 2011-2022 走看看