一次接口分析优化实例

​ 之前写的一个交易调用的接口今天在用的时候发现接口调用的响应时间竟高达15~17s左右,之前埋的坑到现在爆发了,还是得解决。

​ 先简单描述一下接口内容(伪代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//接口的service层
public JSONArray trans(String data){

JSONArray res = new JSONArray();

//1.调用其他接口A
JSONArray tmp = A(data);

//2.对tmp做处理
JSONArray convert = convert(tmp);

//3.将convert作为接口B入参,调用接口B
for(Object o : convert){
res.add(B(convert));
}

return res;
}

​ 我们再来描述一下接口的内容:这个接口不涉及数据库的操作,我把它分为三个部分:在1.处由于A接口是一个分页查询的问题,这里要获取完整A接口的内容会执行多次A接口。在2.处这里会对tmp做处理转换,会用到双重for循环。3.处其实就是将A接口查出的数据作为入参来对B接口进行多次查询。

​ 整个接口的响应时间是十多秒,首先我应该判断是哪一部分耗费了大量时间,于是我修改了一下接口如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//接口的service层
public JSONArray trans(String data){

JSONArray res = new JSONArray();

//1.调用其他接口A
Long begin1 = System.currentTimeMillis();
JSONArray tmp = A(data);
Long end1 = System.currentTimeMillis();
System.out.println("time1 = "+ (end1-begin1)/1000);

//2.对tmp做处理
Long begin2 = System.currentTimeMillis();
JSONArray convert = convert(tmp);
Long end2 = System.currentTimeMillis();
System.out.println("time2 = "+ (end2-begin2)/1000);

//3.将convert作为接口B入参,调用接口B
Long begin3 = System.currentTimeMillis();
for(Object o : convert){
res.add(B(convert));
}
Long end3 = System.currentTimeMillis();
System.out.println("time3 = "+ (end3-begin3)/1000);

return res;
}

​ 在这里我分别计算了三部分代码块执行的时间,得出结论是:

1
2
3
time1 = 1
time2 = 0
time3 = 16

​ 这里我们发现是接口慢主要是由于多次调用其他接口造成的,而在接口中的一些for循环并没有我们想象中的更浪费时间。事实上,在postman中单独调用一次B接口耗时约500ms,这个成本是很大的,我需要尽可能的少调用接口或者说一次请求尽可能请求更多内容。

​ 在这个接口中,我发现convert中的内容很多是重复的,它们仅需要请求一次接口即可,我这里通过优化2.中的代码根据业务逻辑简化并给转换时顺便过滤去重了一下,convert的长度从几十降低到了个位数,我再次请求这个接口,耗时大约在2-3秒,目前也算是能用了,如果不修改AB接口或者整体的调用逻辑的话,其实也没有多少优化空间了。

​ PS:今天顺便跟前辈讨论了一下这个问题,主要是吐槽目前项目拉的很这个接口一样,很大一部分原因就是很多内容应该是包含在前端中而不应该全部都去请求后端接口,这样搞不卡才怪,奈何前端莫的经验,我也莫的经验且人微言轻且重构真的很费时间和资源,还是就这样吧hh。