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

  • 相关阅读:
    全国城市经纬度
    CentOS下SSH无密码登录的配置
    Nginx 1.9+PHP5.6 环境搭建
    Sphinx 2.2.11-release reference manual
    JVM 内存管理机制
    solr 3.5.0 与 tomcat 7.0.5 整合配置
    lucene 分词实现
    lucene 索引 demo
    lucene 搜索demo
    Lucene 简单API使用
  • 原文地址:https://www.cnblogs.com/wgslucky/p/11270038.html
Copyright © 2011-2022 走看看