接口超时问题汇总
接口超时问题汇总
1.网络异常
1.1 网络抖动 网络丢包可能会导致接口超时。
2.1 带宽被占满
服务器带宽指的是在一定时间内传输数据的大小,比如:1秒传输了10M的数据。
所以对于有些高并发请求场景,需要评估一下是否需要增加服务器带宽。
2.线程池满了
在java8之前可以通过实现Callable接口,获取线程返回结果。
java8以后通过CompleteFuture类实现该功能。我们这里以CompleteFuture为例:
如果是因为核心线程池设置太小,可以将其调大一些。
如果是因为多种业务场景共用了同一个线程池,可以拆分成多个线程池。
3.数据库死锁
你提供的API接口中通过某个id更新某条数据,此时,正好线上在手动执行一个批量更新数据的sql语句。
该sql语句在一个事务当中,并且刚好也在更新那条数据,可能会出现死锁的情况。
所以建议在执行数据库批量操作前,一定要评估数据的影响范围,不要一次性更新太多的数据,不然可能会导致很多意想不到的问题。
此外,批量更新操作建议在用户访问少的时段执行,比如:凌晨。
4.传入参数太多
因为数据库在执行sql语句之前,会评估一下耗时情况,查询条件太多,有可能走全表扫描更快。
所以这种情况下sql语句可能会丢失索引,让执行时间变慢,出现接口超时问题。
因此我们在设计批量接口的时候,建议要限制传入的集合的大小,比如:500。
该限制一定要写到接口文档中,避免接口调用方,在生产环境调用接口失败而踩坑。要在接口开发阶段通知到位。
如果我们重新进行系统设计改动比较大的话,有个临时的解决方案:在接口调用方中多线程分批调用该接口,最后将结果进行汇总。
5.超时时间设置过短
通常情况下,建议我们在调用远程API接口时,要设置连接超时时间和读超时时间这两个参数,并且可以动态配置。
并发量不大的业务场景,可以将这两个超时时间设置稍微长一点,比如:连接超时时间为10秒,读超时时间为20秒。
并发量大的业务场景,可以设置成秒级或者毫秒级。
因此,不建议多种业务场景共用同一个超时时间,最好根据并发量的不同,单独设置不同的超时时间。
6.一次性返回数据太多
查看日志发现,该API接口一次性返回的数据太多,而且该数据的更新时间相同。
这就可以断定,该API接口提供方进行了批量更新操作,修改了大量的数据,导致该问题的发生。
所以第三方这种根据日期查询增量数据的接口,建议做成分页查询的,不然后面没准哪一天,遇到批量更新的操作,就可能出现接口超时的问题。
7. 死循环
死循环其实有两种:
普通死循环
无限递归
7.1 普通死循环
还有一种隐藏的比较深的死循环,是由于代码写的不太严谨导致的。如果用正常数据,可能测不出问题,但一旦出现异常数据,就会立即出现死循环。
7.2 无限递归
建议写递归方法时,设定一个递归的深度,比如:分类最大等级有4级,则深度可以设置为4。然后在递归方法中做判断,如果深度大于4时,则自动返回,这样就能避免无限递归的情况。
8.sql语句没走索引
mysql在执行某条sql语句之前,会通过抽样统计来估算扫描行数,根据影响行数、区分度、基数、数据页等信息,最后综合评估走哪个索引。
必要时可以使用force index来强制查询sql走某个索引。
9.服务OOM
link: ElasticSearch服务Java内存异常分析和排查解决OOM
https://www.cnblogs.com/oktokeep/p/18205278
10.在debug
由于你在idea的debug模式中,一直都没有提交事务,会导致死锁的时间变得很长,从而导致业务页面请求的API接口出现超时问题。