性能优化之接口优化(spring/java/http接口) - 高飞网
1180 人阅读

性能优化之接口优化(spring/java/http接口)

2017-07-28 02:09:46

优化工具与措施

CAT(Central Application Tracking):是基于Java开发的实时应用监控平台,为大众点评网提供了全面的监控服务和决策支持。更多介绍可以查看链接:https://github.com/dianping/cat
放水系统:在一个线程内,两次且相同参数调用同一个接口,计为一次放水,放水系统中可以查询是否对平台接口有滥用的情况,对合理使用平台接口提供优化支持。
后台日志(接口事件日志,慢sql日志):不同公司会有不同的日志系统,通过日志可以查询接口的响应时间,如果开通了慢sql日志(基于数据库或应用程序的),则可以对慢sql进行跟踪优化。


优化标准

    快过年了,业务需求不是那么多,于是公司着手对一些性能比较差的接口进行性能优化。首选给出了下面的标准(经验值,一般来讲,用户端接收一个请求,比较好的响应时间在30-50ms,用户会没有慢的感知的):

100<QPS <=N,   Time:<5ms
20  <QPS <=100,Time:<10ms
10  <QPS <=20,  Time:<20ms
5    <QPS <=10,  Time:<50ms
0    <QPS <=5,    Time:<100ms


发现优化点并优化

根据上面的标准,qps在100以上的,要求响应时间小于5ms;qps在20到100之间的,响应时间小于10ms。第一步,我查了cat的接口业务列表(因代码保密对部分数据进行了隐藏):


如上图所示,这里有一个接口,qps是31.9,响应时间avg:11.4,95line是12.2。因此就需要优化。

找到了要优化的接口以后,就要看看如何去优化它。

接口分析1,依然是看cat接口调用图,如下:

能够看到,该接口做了大量重复的操作,循环的使用了相同的sql,相同的接口等,但由于调用接口传参数不同,因此不能计为放水。接合代码,看到该接口是一个更新状态的业务,因为是批量接口,因此for循环了一个单条更新业务的方法。问题就出来了,由于在for循环中,所以的操作时间复杂度都变为了O(n)。
优化方案:
接口变慢的原因很简单,就是数据库、接口太频繁了,浪费了大量的网络IO。
1)第一步要将for循环中的查询改为单条sql查询;
2)如果业务端调用了返回一条数据的接口,可以通过协调沟通,让对方提供一个批量查询接口;
3)除了主流业务,还有一些消息通知,邮件或短信通知等,这些业务不是主流业务,错了也不会影响主流业务的进行,因此把这部分业务封装为一个异步方法,采用异步的方式去调用;

再看另一个接口:

这个接口很特殊,本身业务非常简单,就是先查询一下,再更新回去,但因为这个Entity配置上使用了一级缓存,因此,当缓存没有命中时,查询的数据都要加到缓存中去,接口去批量更新,又会把缓存给删掉,非常浪费性能。
优化方案:
把一级缓存去掉。


放水接口

通过放水系统,查询平台的放水情况:

再看一下具体对哪些平台的哪些接口放水了,由哪些接口放的:

根据上面的数据,我们就定位到了具体的优化点,去查询代码,并优化。

以其中一个接口为例,情况是,接口首选要调用a方法,a方法中查询了用户信息,然后进行一系列别的操作,返回一个boolean值,然后,接口进行一些中间操作,最后去保存数据的时候,调用了b方法,b方法中也需要使用用户信息,因此也查询了一遍,造成了放水。

优化方案:
在a方法查询到用户信息以后,将用户信息放置在ThreadLocal中,b方法查询用户信息时,先查询TheadLocal是否存在,如果存在就直接用,不存在时再调用平台接口查询。


子业务相互独立

    如果一个大业务方法中,各子业务相互独立,互不依赖,而此时业务耗时又不达标时,可以考虑使用并发处理,即多线程并发查询数据。有个前提是该接口应至少高于20ms,如果再低,线程切换等因素可能会抵消掉多线程带来的性能提高。

还没有评论!
54.92.158.65