记录一次请求超时问题

问题背景 项目是关于开发一个看板类网站。上线后在使用过程中偶发性的报http请求超时。请求是使用axios,超时时间设置为10s。
记录一次请求超时问题
文章图片

分析过程 必须是后台的锅
遇到超时问题,首先怀疑的就是后台接口返回超时了。而刚好后台也找到了差不多时间段的错误日志,根据日志分析又怀疑是hbase连接超时问题。
通过后台与大数据同事的一通操作,问题仍在,但出问题时错误日志却没了。
前端上场
猜想无果,只能从前端开始正向分析。

  1. 首先,分析Http请求各个阶段的耗时情况。(用Fiddler和Chrome timing工具,实际上两者看不出太多区别。)
    记录一次请求超时问题
    文章图片

    从整个耗时来看,并没有超过10s。其中有异常的地方在于TCP/IP Connect耗时较长。
  2. 根据上一步的分析,有两个怀疑点。第一个,TCP/IP Connect是不是由于域名解析耗时造成的,通过直连ip,并没有改善。第二个,前端同一时刻并发请求太多,请求排队,导致超时,通过限制并发数,问题仍在。
    记录一次请求超时问题
    文章图片
  3. 分析无果,回过头来看一下axios超时原理。通过看源码,实际上就是使用的xhr的timeout属性,这是ajax标准语法。
  4. 此时有点怀疑是服务器配置问题。原理上来说,Http请求结束,释放TCP连接后,服务器端TCP连接仍将keep-alive 1-3分钟。如果短期内有过多的请求触发,可能存在连接不够,重连超时问题。我通过不停的切换页面,频繁调用接口,在短时间内重现了此问题。此时终于找到了稳定重现方式。
  5. 根据上一节的分析,我们查看了服务器资源配置,服务器日志,都没有问题。同时在同一台电脑上,当前页面报错。立马重开一个tab页,重新打开此页面,却不报错。基本又排除是服务器问题。
  6. 突发灵感,看一下内存变化。发现页面内存达到250M,有异常。
  7. 【记录一次请求超时问题】通过分析,确实内存在页面切换过程中不停增长,切主动回收后不能复原。
    内存分析手段:使用Chrome Memory快照,根据字段名称部分能看出来是哪个元素。
    内存泄漏原因:
    1. Vue component方法被赋值给window变量,导致component不能回收
    2. axios cancelToken引用全局变量,导致所有的xhr完成后不能回收。此处有点奇怪,没有细分析。
    3. echart需要在vue beforeDestroy阶段主动dispose,否则不能回收

    推荐阅读