没想到一个简单的HTTP请求会对系统产生如此巨大的影响,这让我深感开发世界中,哪怕是一点点的分析失误,都可能导致巨大的损失。
1. 背景
在一次测试中发现接口的性能总是很低很低,完全没有达到自己的预期,甚至感觉有点不可思议,因为低的没有心理准备,一直在想到底是哪里出问题了,然后一步步进行拆解分析,最终发现了罪魁祸首。
2. 祸源
经过不断的压测分析发现程序中使用的http请求方式的问题,先来说说这次问题的实现方式,
//引入的类
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;
//具体方法实现
Client client = Client.create();
client.setConnectTimeout(1000);
client.setReadTimeout(3000);
URI u = new URI(url);
WebResource resource = client.resource(u);
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
params.add("paramJson", param1);
params.add("accessSys", param2);
String response = resource.type(MediaType.APPLICATION_FORM_URLENCODED).post(String.class, params);
resultPojo.setStatus(200);
resultPojo.setData(response);
在这个例子中发现每次发送http请求前都要进行create进行客户端的创建,当并发大的时候创建的客户端的数量也会增加,因为cpu固定,导致cpu使用时间的切换变大导致等待时间加长,进而影响整体性能。
3. 解决方式
使用httpClient的方式并创建线程池来管理连接,方便管理客户端的数量,将上述方式采用http方式进行更换后性能提升了好多。
//设置线程池
static {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(100);
cm.setDefaultMaxPerRoute(20);
httpClient = HttpClients.custom().setConnectionManager(cm).build();
}
//post请求方式
CloseableHttpResponse response = null;
BufferedReader in = null;
String result = "";
try {
HttpPost httpPost = new HttpPost(url);
// 设置form-data 请求参数
if (params != null) {
List<NameValuePair> list = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : params.entrySet()) {
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list);
httpPost.setEntity(formEntity);
}
// 设置请求头
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPost.setHeader(entry.getKey(),entry.getValue());
}
}
// 请求相关配置
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(1000).setConnectionRequestTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(requestConfig);
// 设置content-type 为form表单形式
httpPost.addHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
httpPost.setHeader("Accept", "application/json");
// 发送请求
response = httpClient.execute(httpPost);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder stringBuilder = new StringBuilder();
String line = "";
while ((line = in.readLine()) != null) {
stringBuilder.append(line);
}
result = sbstringBuildertoString();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != response) {
response.close();
}
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
4. 总结
基于我自己的项目在未调整前在50并发的时候响应耗时10秒,最高到达19秒,在调整后50并发的影响在1秒左右,100并发在2秒左右,提升真的很高,通过这次的排查真是在程序的世界里任何一点想不到都有可能对系统造成很大的影响。
记录下来自己的一次成长!!!