在很早之前我就有个想法,如果有一个服务能把我的请求放大 N 倍发送给服务端,那就可以更加灵活地将接口的功能测试用例和性能测试用例结合在一起。只需要设置一些参数,就可以在本地控制请求QPS
,比如每秒 100 次,然后通过服务器放大 100 倍,那么请求到被测服务的QPS
就是10000倍了。
但是由于当时技术水平比较菜,主要考虑到:1、当时面临被测服务的QPS
有限,不需要这个功能;2、为了这个需求写个用不到的服务,无法落地。所以就放弃了。
在最近更新DCS_FunTester
分布式压测框架的时候,我又回想起来这件事情,如此前面两个考虑的因素基本解决。说干就干,先上再说。计划主要用于以QPS
为主要标准的压测,而非并发或线程。
首先由master
节点接受请求信息,然后分配给一个slave
节点去按照倍数执行(采用 for 循环),不计入性能测试状态。
没有使用FunTester
测试框架中的性能模板,因为放大倍数比较少,整体来说消耗不大。目前自己测试结果来讲,没有遇到大的问题,这跟用户就我一个人有关系。
定位就是在被测接口QPS
在 1 万以内,通过本地请求,分布式执行放大请求倍数,达到性能测试的目的,当然比较粗略。
以后遇到新需求再优化,目前重点放在HTTP
协议,其他协议接口未来会支持。
实现方法:
@Override
void runRequest(ManyRequest request) {
def host = NodeData.getRunHost(1)
MasterManager.runMany(host, request)
}
工具类代码:
/**
* 运行放大器
* @param host
* @param request
* @return
*/
static boolean runMany(String host, ManyRequest request) {
String url = SlaveApi.RUN_MANY;
def response = getPostResponse(host, url, request)
isRight(response)
}
实现方法:
@Async
@Override
public void runMany(ManyRequest request) {
FunRequest funRequest = FunRequest.initFromJson(request.toJson());
HttpRequestBase requestBase = funRequest.getRequest();
Integer times = request.getTimes();
try {
for (int i = 0; i < times; i++) {
FunLibrary.executeSimlple(requestBase);
}
} catch (Exception e) {
FailException.fail(e.getMessage());
}
}
使用了异步执行,有机会评估异步和同步对服务性能影响。
这里用到了FunTester
测试框架的方法。
/**
* 简单发送请求,此处不用{@link CloseableHttpResponse#close()}也能释放连接
*
* @param request
*/
public static String executeSimlple(HttpRequestBase request) throws IOException {
CloseableHttpResponse response = ClientManage.httpsClient.execute(request);
return getContent(response.getEntity());
}
slave
节点用的是Java
写的,后期DCS_FunTester
可能会出一个纯Java
版本。
@ApiModel(value = "单请求放大器参数")
class ManyRequest extends AbstractBean {
private static final long serialVersionUID = -49090532920398509L;
@Pattern(regexp = "get|post|Get|Post|GET|POST", message = "请求方法错误!")
String requestType
@NotBlank
@Pattern(regexp = "http.*", message = "请求url错误")
String uri
@NotNull
JSONObject args
@NotNull
JSONObject params
@NotNull
JSONObject json
@NotNull
JSONArray headers
@Length(min = 10, max = 100, message = "倍数范围错误")
Integer times
}