写点什么

写一个并发测试工具

用户头像
罗亮
关注
发布于: 2020 年 07 月 18 日

jmeter之类的工具应该说是非常好用的了,但是自己写的工具会更加的灵活,想怎么玩就怎么玩。



要求

我们首先要看下请求参数:

  • url : 我们要测试的URL

  • total 总共要发送多少次请求

  • per 每次提交多少次的并发



返回的参数:

  • avgTime 平均的响应时间

  • percentile95Time : 95%的响应时间



好啦,清楚需要什么,要返回什么,我们就可以开始写代码了。



代码实现

返回结果的类 , 我使用了lombok 生成get&set方法。

@Data
public class Result {
/** 平均响应时间 */
private Integer avgTime;
/** 95% 的响应时间 */
private Integer percentile95Time;
}



主要的逻辑代码如下:

public class RequestTool {
/**
* 获取结果的类
*/
private Map<String,Long> resultMap = new ConcurrentHashMap<String, Long>() ;
/** 使用 okhttp 作为请求工具 */
private OkHttpClient client = new OkHttpClient.Builder().build();
private CountDownLatch countDownLatch ;
private int total;
/**
* 并发测试请求
* @param url 请求URL
* @param total 请求总数
* @param per 并发数
* @return
*/
public Result request(final String url ,int total,int per) throws Exception {
// 新建一个线程池
ExecutorService executorService = Executors.newFixedThreadPool(per);
this.countDownLatch = new CountDownLatch(total);
this.total = total;
// 执行请求
for (int i = 0; i < total; i++) {
final int requestNum = i+1;
executorService.execute(new Runnable() {
public void run() {
doRequest(requestNum ,url);
}
});
}
countDownLatch.await();
executorService.shutdown();
return calResult();
}
private Result calResult() {
List<Long> list = new ArrayList<Long>(resultMap.values());
Collections.sort(list);
System.out.println("request results : " + JSON.toJSONString(list));
int totalTime = 0;
int percentile95Time = 0;
int times = (int)(total * 0.95);
int size = list.size();
for (int i = 0; i < size; i++) {
Long item = list.get(i);
totalTime += item;
if(i < times ){
percentile95Time += item;
}
}
Result result = new Result();
result.setAvgTime( totalTime/ size);
result.setPercentile95Time( percentile95Time / times );
return result;
}
private void doRequest(int requestNum, String url) {
long start = System.currentTimeMillis();
try {
Request request = new Request.Builder().url(url).get().build();
Response response = client.newCall(request).execute();
if(response.code() != 200){
System.out.println(" requestNum = "+requestNum+", code = " + response.code());
}
} catch (IOException e) {
System.out.println(" reuqest error : " + e.getLocalizedMessage() );
}finally {
long end = System.currentTimeMillis() - start;
resultMap.put(String.valueOf(requestNum),end );
countDownLatch.countDown();
}
}
}



执行test

/**
* 并发测试工具类
*/
public class ConcurrentHttpTest {
public static void main(String[] args) {
RequestTool requestTool = new RequestTool();
// 偷偷的测试了下 百度翻译 100请求,10并发。
String url = "https://fanyi.baidu.com/#en/zh/per";
try {
Result result = requestTool.request( url, 100, 10);
System.out.println(" result : " + JSON.toJSONString(result));
} catch (Exception e) {
e.printStackTrace();
}
}
}

测试结果:

request results(每次请求的结果) : [200,203,213,217,218,237,250,252,280,282,298,314,317,325,345,353,354,359,361,363,366,367,368,369,375,376,376,390,397,398,404,404,407,428,431,437,437,439,440,444,449,451,451,455,458,465,466,475,477,477,480,487,494,494,495,502,503,503,517,523,532,539,540,543,546,547,555,560,568,570,570,587,597,599,609,611,615,623,631,634,644,661,664,673,678,686,689,694,705,736,759,765,777,816,870,873,922,1722,1945,2187]



result(计算平均响应时长) : {"avgTime":534,"percentile95Time":482}



maven依赖库

我的maven依赖:

<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.72</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>



用户头像

罗亮

关注

种树最好的时间是十年前,其次是现在。 2017.09.10 加入

神秘的程序猿

评论

发布
暂无评论
写一个并发测试工具