HttpClient 连接池配置和使用

在游戏项目开发中,经常会向其它的服务发送一些Http请求,获取一些数据或验证。比如充值,SDK验证等。如果每次都重新创建一个新的HttpClient对象的话,当并发上来时,容易出现异常或连接失败,超时。这里可以使用HttpClient的连接池配置,减少HttpClient创建的数量,减少资源开销。

1package com.mygame.common.utils; 2 3import java.io.IOException; 4import java.security.KeyManagementException; 5import java.security.KeyStoreException; 6import java.security.NoSuchAlgorithmException; 7import org.apache.http.Header; 8import org.apache.http.HttpStatus; 9import org.apache.http.client.config.RequestConfig; 10import org.apache.http.client.methods.CloseableHttpResponse; 11import org.apache.http.client.methods.HttpGet; 12import org.apache.http.client.methods.HttpPost; 13import org.apache.http.config.Registry; 14import org.apache.http.config.RegistryBuilder; 15import org.apache.http.conn.socket.ConnectionSocketFactory; 16import org.apache.http.conn.socket.PlainConnectionSocketFactory; 17import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 18import org.apache.http.conn.ssl.TrustSelfSignedStrategy; 19import org.apache.http.entity.StringEntity; 20import org.apache.http.impl.client.CloseableHttpClient; 21import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; 22import org.apache.http.impl.client.HttpClients; 23import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 24import org.apache.http.ssl.SSLContextBuilder; 25import org.apache.http.util.EntityUtils; 26import org.slf4j.Logger; 27import org.slf4j.LoggerFactory; 28import com.alibaba.fastjson.JSON; 29 30public class GameHttpClient { 31 private static Logger logger = LoggerFactory.getLogger(GameHttpClient.class); 32 // 池化管理 33 private static PoolingHttpClientConnectionManager poolConnManager = null; 34 35 private static CloseableHttpClient httpClient;// 它是线程安全的,所有的线程都可以使用它一起发送http请求 36 static { 37 try { 38 System.out.println("初始化HttpClientTest~~~开始"); 39 SSLContextBuilder builder = new SSLContextBuilder(); 40 builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); 41 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); 42 // 配置同时支持 HTTP 和 HTPPS 43 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslsf).build(); 44 // 初始化连接管理器 45 poolConnManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); 46 poolConnManager.setMaxTotal(640);// 同时最多连接数 47 // 设置最大路由 48 poolConnManager.setDefaultMaxPerRoute(320); 49 // 此处解释下MaxtTotal和DefaultMaxPerRoute的区别: 50 // 1、MaxtTotal是整个池子的大小; 51 // 2、DefaultMaxPerRoute是根据连接到的主机对MaxTotal的一个细分;比如: 52 // MaxtTotal=400 DefaultMaxPerRoute=200 53 // 而我只连接到http://www.abc.com时,到这个主机的并发最多只有200;而不是400; 54 // 而我连接到http://www.bac.com 和 55 // http://www.ccd.com时,到每个主机的并发最多只有200;即加起来是400(但不能超过400);所以起作用的设置是DefaultMaxPerRoute 56 // 初始化httpClient 57 httpClient = getConnection(); 58 59 System.out.println("初始化HttpClientTest~~~结束"); 60 } catch (NoSuchAlgorithmException e) { 61 e.printStackTrace(); 62 } catch (KeyStoreException e) { 63 e.printStackTrace(); 64 } catch (KeyManagementException e) { 65 e.printStackTrace(); 66 } 67 } 68 69 public static CloseableHttpClient getConnection() { 70 RequestConfig config = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(5000).build(); 71 CloseableHttpClient httpClient = HttpClients.custom() 72 // 设置连接池管理 73 .setConnectionManager(poolConnManager) 74 .setDefaultRequestConfig(config) 75 // 设置重试次数 76 .setRetryHandler(new DefaultHttpRequestRetryHandler(2, false)).build(); 77 return httpClient; 78 } 79 80 public static String httpGet(String url) { 81 HttpGet httpGet = new HttpGet(url); 82 CloseableHttpResponse response = null; 83 84 try { 85 response = httpClient.execute(httpGet); 86 String result = EntityUtils.toString(response.getEntity()); 87 int code = response.getStatusLine().getStatusCode(); 88 if (code == HttpStatus.SC_OK) { 89 return result; 90 } else { 91 logger.error("请求{}返回错误码:{},{}", url, code,result); 92 return null; 93 } 94 } catch (IOException e) { 95 logger.error("http请求异常,{}",url,e); 96 } finally { 97 try { 98 if (response != null) 99 response.close(); 100 } catch (IOException e) { 101 e.printStackTrace(); 102 } 103 } 104 return null; 105 } 106 public static String post(String uri, Object params, Header... heads) { 107 HttpPost httpPost = new HttpPost(uri); 108 CloseableHttpResponse response = null; 109 try { 110 StringEntity paramEntity = new StringEntity(JSON.toJSONString(params)); 111 paramEntity.setContentEncoding("UTF-8"); 112 paramEntity.setContentType("application/json"); 113 httpPost.setEntity(paramEntity); 114 if (heads != null) { 115 httpPost.setHeaders(heads); 116 } 117 response = httpClient.execute(httpPost); 118 int code = response.getStatusLine().getStatusCode(); 119 String result = EntityUtils.toString(response.getEntity()); 120 if (code == HttpStatus.SC_OK) { 121 return result; 122 } else { 123 logger.error("请求{}返回错误码:{},请求参数:{},{}", uri, code, params,result); 124 return null; 125 } 126 } catch (IOException e) { 127 logger.error("收集服务配置http请求异常", e); 128 } finally { 129 try { 130 if(response != null) { 131 response.close(); 132 } 133 } catch (IOException e) { 134 e.printStackTrace(); 135 } 136 } 137 return null; 138 } 139 140}

 


QQ交流群:66728073,197321069

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )