前端:Vue 2.0 后台:Node Express 浏览器:Chrome 部署系统:Linux
在现有项目的基础之上增长了两个页面,可是在使用的过程当中发现,当连续操做几回以后页面会变得奇慢无比,查看接口调用发现接口请求长时间处于pending状态,可是等1-2分钟左右接口仍是会返回应答结果。以下图所示:前端
经过反复复现该问题(在各个页面之间不一样切换,触发请求),发现了一个规律,就是每次在第7次页面切换的时候,全部接口都会被阻塞并在1分多钟以后才返回。node
看看这1分多钟究竟花在了哪里?git
从上图能够看到,整个接口请求的大部分时间都花在了Stalled阶段。如今的问题是Stalled是啥意思?下面是一段比较浅显的解释:github
Time the request spent waiting before it could be sent. This time is inclusive of any time spent in proxy negotiation.Additionally, this time will include when the browser is waiting for an already established connection to become available for re-use, obeying Chrome’s maximum six TCP connection per origin rule.
从上面的解释看,可能有两个缘由:web
首先看第一个问题,TCP链接是否正常?chrome
$ lsof -i:8700 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME node 26315 mumingv 12u IPv4 449215145 0t64 TCP *:8700 (LISTEN) node 26315 mumingv 16u IPv4 449217569 0t64 TCP localhost:8700->172.24.186.14:54064 (ESTABLISHED) node 26315 mumingv 17u IPv4 449217570 0t64 TCP localhost:8700->172.24.186.14:54065 (ESTABLISHED) node 26315 mumingv 18u IPv4 449217580 0t64 TCP localhost:8700->172.24.186.14:54066 (ESTABLISHED) node 26315 mumingv 19u IPv4 449217581 0t64 TCP localhost:8700->172.24.186.14:54067 (ESTABLISHED) node 26315 mumingv 20u IPv4 449226874 0t64 TCP localhost:8700->172.24.186.14:54574 (ESTABLISHED) node 26315 mumingv 21u IPv4 449217583 0t64 TCP localhost:8700->172.24.186.14:54069 (ESTABLISHED)
上图中,8700
是网站的服务端口号,172.24.184.14
是Chrome浏览器所在Mac的IP。在复现问题的过程当中一直执行lsof -i:8700
持续进行观察发现,当在第7次页面切换的时候,这里的TCP链接数量再也不增长,维持在6个左右且状态都是ESTABLISHED(已创建)
。因此能够基本排除TCP链接的问题。express
固然,也能够经过netstat命令查询TCP链接状态。json
$ netstat -tunpa | grep 8700 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:8700 0.0.0.0:* LISTEN 27765/node tcp 0 0 10.95.199.140:8700 172.24.186.14:65413 ESTABLISHED 27765/node tcp 0 0 10.95.199.140:8700 172.24.186.14:65412 ESTABLISHED 27765/node tcp 0 0 10.95.199.140:8700 172.24.186.14:65421 ESTABLISHED 27765/node tcp 0 0 10.95.199.140:8700 172.24.186.14:65420 ESTABLISHED 27765/node tcp 0 0 10.95.199.140:8700 172.24.186.14:65419 ESTABLISHED 27765/node tcp 0 0 10.95.199.140:8700 172.24.186.14:65422 ESTABLISHED 27765/node
再来看第二个问题,TCP链接被谁占用了不释放?后端
看看是否是有其余请求占用了这些TCP链接,查看全部请求,果不其然:浏览器
原来每次在页面切换的时候,浏览器都会默认发送一个请求获取一次网页图标,这个不是前端业务逻辑主动调用的XHR请求,但对于后端来讲也是一次GET请求。
实际上,若是没有要求显示特定网页图标的话,后端随便返回一个信息就行了,不用非得准备一个网页图标。浏览器拿不到图标的话会显示一个默认图标。
问题找到了,看看为啥后端为啥没有返回图标并加以解决就行了。具体到这个项目,是在node express的app.js入口文件中没有注册相应的处理逻辑。
// 接口路由 loadRouter(app, '/project-name', path.join(__dirname, 'app/controllers')); // 静态页面 app.use('/project-name', express.static(path.join(__dirname, "webroot", "project-name"))); // favicon.ico和其余不支持的请求 app.get("*", function(req, res) { if (req.path === "/favicon.ico") { return; // !!!这里不能直接return,须要返回具体的内容,不然会阻塞express框架返回应答消息!!! } throw new PathError(); });
知道问题后,修改就很简单了。
app.get("*", function(req, res) { if (req.path === "/favicon.ico") { res.json({'status':0, msg:''}); // 这里随便返回个内容就行,不影响浏览器使用默认图标进行展现 } throw new PathError(); });
至此,问题解决。
TCP链接资源数量有限,若是不限制数量的话,全部TCP所有被占用的话系统就“没法提供服务”了。通常浏览器的并发TCP链接数量都在五、6个左右,对于Chrome来讲是6个。至于为何是这么多,这是各浏览器自行设置的,没有标准。具体解释参考:官方文档。
通常按照以下几步进行排查便可: