上线前的压测问题:
第一版的httpClient请求工具类:
1.由于把地址写成全局变量,每次调用其他系统的接口时:
httpClient.setAddress("136.224.224.36"),httpClient.post();
这种方式导致上一次的请求地址没有被变更,然后请求参数和请求地址不匹配,导致混乱。第三方的系统接收到的参数不正确。
2.当压测进行接口压测的时候,2、3分钟就报了(address already in used)连接数被占满的异常。这是由于没有在请求头中设置关闭连接,如果对面的返回时间较长。会导致连接不释放。method.setRequestHeader("Connection","close");
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
/**
* @ClassName HttpClientUtils
* @Description http 客户端请求工具类
* modify by fee 20151229
* 增加调用日志记录
* @author t-liuyong
* @date 2015-3-15
*/
@Component
public class HttpClientUtils {
private static final Logger log = Logger.getLogger(HttpClientUtils.class);
private static final CloseableHttpClient httpclient = HttpClients.createDefault();
private static final int TIME_OUT = 60000; // 60秒
private String address;
private Boolean devFlag;
// 指定编码格式
private static final String CODING_FORMAT = "text/html;charset=UTF-8";// "application/x-www-form-urlencoded;charset=UTF-8";
// 指定编码格式
private static final String CODING_FORMAT_CMS = "application/json;charset=UTF-8";
/***
* post请求模拟
* @param requestBody
* @param headerMap
* @return
* @throws Exception
*/
public String postInvoker(String requestBody, Map<String, String> headerMap) throws Exception {
HttpClient client = new HttpClient(
new MultiThreadedHttpConnectionManager());
Boolean success = false;
PostMethod method = new PostMethod(address);
// 超时机制
HttpMethodParams methodParams = new HttpMethodParams();
methodParams.setSoTimeout(TIME_OUT);
method.setParams(methodParams);
method.addRequestHeader("Content-Type", CODING_FORMAT);
if(headerMap!=null&&headerMap.size()>0){
Iterator<Entry<String, String>> it = headerMap.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> entry = it.next();
method.addRequestHeader(entry.getKey(), entry.getValue());
}
}
// !!!!!!!!!!!!!!!!!!!!设置代理,正式环境需要去掉!!!!!!!!!!!!!!!!!!!!
/*if (devFlag) {
client.getHostConfiguration().setProxy("proxy6.taikanglife.com",
8080);
}*/
try {
RequestEntity requestEntity = new StringRequestEntity(requestBody,
CODING_FORMAT, "UTF-8");
method.setRequestEntity(requestEntity);
client.executeMethod(method);
// return new String(method.getResponseBody(), "utf-8");
InputStream responseStream = method.getResponseBodyAsStream();
BufferedReader br = new BufferedReader(new InputStreamReader(
responseStream));
StringBuffer sb = new StringBuffer();
String str = "";
while ((str = br.readLine()) != null) {
sb.append(str);
}
success = true;
return sb.toString();
} catch (HttpException e) {
log.error("无法连接到指定地址url:" + address + " " + e.getMessage());
e.printStackTrace();
throw new Exception("无法连接到指定地址url:" + address + " "
+ e.getMessage());
} catch (Exception e) {
log.error("请求失败url:" + address + "*****body*****" + requestBody
+ "*****," + e.getMessage());
e.printStackTrace();
throw new Exception("请求失败url:" + address + "*****body*****"
+ requestBody + "*****," + e.getMessage());
} finally {
method.releaseConnection();
}
}
/*
*发送不带参数的post请求
* @param String url
*/
public static String SendPost(String url){
String result = null;
//得到一个HTTP对象
HttpPost httpPost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
//执行一个httpPost请求,并得到一个CloseableHttpResponse
response = httpclient.execute(httpPost);
//从CloseableHttpResponse中拿到httpEntity
HttpEntity entity = response.getEntity();
//将HttpEntry转换成字符串
result = EntityUtils.toString(entity);
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭CloseableHttpResponse
if (response != null){
try {
response.close();
} catch (IOException e) {
log.error(e.getMessage());
e.printStackTrace();
}
}
}
return result;
}
/***
* post请求模拟(只为上海银行卡支付流程)
* @param requestBody
* @param headerMap
* @return
* @throws Exception
*/
public String specialPostInvoker(String requestBody, Map<String, String> headerMap) throws Exception {
HttpConnectionManager httpConnectionManager=new MultiThreadedHttpConnectionManager();
HttpClient client = new HttpClient(
httpConnectionManager);
HttpConnectionManagerParams httpConnectionManagerParams=httpConnectionManager.getParams();
httpConnectionManagerParams.setDefaultMaxConnectionsPerHost(16);
httpConnectionManagerParams.setMaxTotalConnections(128);
Boolean success = false;
PostMethod method = new PostMethod(address);
// 超时机制
HttpMethodParams methodParams = new HttpMethodParams();
methodParams.setSoTimeout(TIME_OUT);
method.setParams(methodParams);
method.addRequestHeader("Content-Type", CODING_FORMAT);
method.setRequestHeader("Connection","close");
if(headerMap!=null&&headerMap.size()>0){
Iterator<Entry<String, String>> it = headerMap.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> entry = it.next();
method.addRequestHeader(entry.getKey(