快捷目录
前言/背景
在日常开发中,不管是前端还是不同服务之间,都会存在请求接口API服务(从服务器获取数据、与服务器进行各种交互交换数据)操作,因此有时候会发生请求接口很久都得不到响应(即我们常说的接口超时
)、或响应时间过长等情况。那么 如果访问网站或请求接口过程中出现了接口超时,该如何排查? 又该如何处理解决?
别慌,本篇文章或许可以为阁下指点迷津,保证药到命除 呸,是"药到病除"!
好了,废话不多讲,下面正式开始谝闲传,嗷不,是正式开始呈上本文的重点:
接口访问超时 504 Gateway Time-out 问题排查及其解决方案。请收好,准备上车,下方小黄车3号链接,赶紧去拍,啊~~ hahahaha.
一、可能引起接口超时的原因分析:
引发接口请求超时的原因有多个,没有固定的解决法子,只能具体问题具体分析,再就是在不断的实践中一点点积累,积累到一定程度可以凭经验快速定位并解决掉!
但是话说回来,经过大量的实践与积累,我们总能发现或总结出一些相对的规律或方法用于快速的排查和解决接口超时。
比如:接口请求时前端静态资源依赖某些不可达的第三方资源地址;
又比如接口的处理逻辑有问题或逻辑太复杂;
再比如接口的查询sql语句中涉及的数据库表过多、慢sql导致执行时全表扫描(尤其大数据量数据表);
再再比如,嗯,还有吗? 嗯,还真有,而且还不少,比如:
nginx设置的超时时间过短、或者是该接口本身 业务处理较为复杂执行时间长…
等等原因,都可能会造成接口请求很久都没有结果返回,浏览器就会报504 Gateway Time-out提示接口超时。
下面将针对各种常见原因 分别进行具体分析,并给出一种解决方案或处理思路。
.
二、排查及其解决:
总原则:
· · · 从外层到内层;
· · · 优先考虑罪魁祸首最有可能出现的地方,再考虑配置、硬件、网络等基础设施。具体如下:
第一步:排查接口中请求的前端静态资源:
从外层开始,层层递进,先查看是否是前端资源依赖问题所致。
操作:通过F12打开浏览器开发者工具,进入network板块,查看各资源文件的响应时间。
.
目的 :看Network栏中哪个文件时间最长,从而确定是否有可能css或者js插件引用了一些被国内墙住的国外地址,导致请求时间过长一直请求不到。
.
处理方法:找到相关的地方注释,或者引用本地的,然后重新发起请求并观察请求结果。
.
第二步:根据对应接口排查sql:
如果文件引用什么的都没问题,考虑是否是sql问题所致,必要时优化sql。
操作:找到该接口涉及的相关sql,在数据库如MySQL中执行一下。
.
目的 :通过执行对应sql,查看执行时间;从而考虑优化sql。
.
处理方法:在数据库中通过执行计划expain一下SQL,查看索引情况之类的,针对性优化
。
.
第三步:排查Nginx超时时间配置:
如果接口对应的sql也没有问题,排查是否是Nginx超时时间配置问题引起(程序执行时间过长导致响应超时)。
分析:例如程序执行需要至少四、五十秒,而nginx最大响应等待时间为30秒,那肯定就会出现超时。
.
处理方法:这种情况可以将nginx的超时时间调大。
.
说明 :这种情况不是最理想的解决办法,因为如果接口请求时间超过20秒的话,接口的性能本身就不够合格,用户体验太差。
因此如果真是代码问题引起的,我们需要从代码层面来改善我们的响应时间,也就是接下来说的第四步。
.
第四步:排查接口代码本身:
如果ng的超时配置亦没问题,检查是否是接口代码逻辑的问题。
操作:确定是哪个接口后,查看这个接口的内部逻辑是怎样的,做了哪些事情,梳理并进行优化改进。
.
处理方法:可以对该接口方法的相关处理逻辑进行代码走读,尝试找到耗时的地方并进行改造、优化逻辑;也可以通过如下办法快速定位接口有问题的位置:
具体举措为:添加日志快速定位
接口响应超时,我们最急迫想知道的是接口的哪部分代码出了问题。可以使用日志快速定位超时代码的位置,也就是:
. 1)在方法的不同关键位置/模块,加上对应的日志输出,并记得日志附带打 印时间,然后将代码打包发布到生产环境;
. 2)在生产环境中请求接口,日志就会记录下来,通过观察方法执行过程中记录的日志时间差(方法中不同模块的执行时间),来判断哪部分代码执行时间过长,然后针对此模块进行具体分析,比如查看是否嵌套轮询、是否死循环等,找到问题后进行相应的优化。
.
第五步:排查网络、硬件、配置环境之类的其他因素:
如果前几步都没有问题,则排查网络情况、硬件、配置环境之类的问题,比如:
查看是否是网络运营服务商导致网络延迟或数据丢包。
解决办法:通过换用不用网络,比如用其他教育网,联通网啥的环境试一下看是否也慢,如果慢,可以考虑采用CDN加速策略,或者想其他办法了。
.
三、总结:
总之,接口超时、接口响应慢,排查大致可以从如下几方面入手:
- 前端资源层面,某些插件是否请求了被墙的国外地址
- 依赖于第三方接口,导致因第三方请求拖慢了本地请求
- 针对查询类接口,是否添加缓存,如果已添加,是否是热点数据导致负载不均衡(主要针对接口响应慢问题)
- 接口本身涉及业务太多,导致程序执行需要跑很久(超过Ng配置的超时时间)
- sql层面的问题导致的数据加载慢,进而拖慢接口
- 代码逻辑、质量等导致,如出现内存泄漏,死锁等导致重复循环读取
- 网络原因?带宽不足?DNS解析慢?硬件、配置环境之类的问题。