摘要:開發環境前端后臺瀏覽器部署系統問題現象在現有項目的基礎之上增加了兩個頁面,但是在使用的過程中發現,當連續操作幾次之后頁面會變得奇慢無比,查看接口調用發現接口請求長時間處于狀態,但是等分鐘左右接口還是會返回應答結果。
開發環境
前端:Vue 2.0 后臺:Node Express 瀏覽器:Chrome 部署系統:Linux問題現象
在現有項目的基礎之上增加了兩個頁面,但是在使用的過程中發現,當連續操作幾次之后頁面會變得奇慢無比,查看接口調用發現接口請求長時間處于pending狀態,但是等1-2分鐘左右接口還是會返回應答結果。如下圖所示:
原因分析通過反復復現該問題(在各個頁面之間不同切換,觸發請求),發現了一個規律,就是每次在第7次頁面切換的時候,所有接口都會被阻塞并在1分多鐘之后才返回。
看看這1分多鐘究竟花在了哪里?
從上圖可以看到,整個接口請求的大部分時間都花在了Stalled階段。現在的問題是Stalled是啥意思?下面是一段比較淺顯的解釋:
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.
從上面的解釋看,可能有兩個原因:
TCP連接出問題了,一直無法建鏈成功;
TCP連接是OK的,但是一直被占用無法使用。
首先看第一個問題,TCP連接是否正常?
$ 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連接的問題。
當然,也可以通過netstat命令查詢TCP連接狀態。
$ 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(); });
至此,問題解決。
FAQ Q:為什么瀏覽器和服務端之間最多只能創建6個TCP連接?TCP連接資源數量有限,如果不限制數量的話,所有TCP全部被占用的話系統就“無法提供服務”了。一般瀏覽器的并發TCP連接數量都在5、6個左右,對于Chrome來說是6個。至于為什么是這么多,這是各瀏覽器自行設置的,沒有標準。具體解釋參考:官方文檔。
Q:后續如何排查這類接口問題?一般按照如下幾步進行排查即可:
瀏覽器端看XHR請求,判斷XHR請求本身是否有異常;
瀏覽器端看ALL請求,判斷非XHR請求是否有異常;
服務器端查看服務本身是否正常;
服務器端查看服務建立的TCP連接是否正常;
抓包查看TCP交互和業務請求交互報文是否有異常。
參考資料Network Issues Guide
Understanding Resource Timing
chrome的timeline中stalled問題解析
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/109935.html
摘要:在模式下粘貼速度很慢的問題一般當我們在模式下粘貼一段超大量的文本,比如行。更新后無法打開問題很久不使用安裝東西,安裝了一個小軟件,結果直接更新到版本,然后導致完全無法打開。 Vim 在Insert模式下粘貼速度很慢的問題 一般當我們在Insert模式下粘貼一段超大量的文本,比如1000行。那么Vim會變得奇慢無比,大概半分鐘? 所以,如果我們要粘貼文本,需要用另一種方法:在Normal...
閱讀 3541·2021-11-18 10:02
閱讀 3110·2019-08-29 18:34
閱讀 3397·2019-08-29 17:00
閱讀 430·2019-08-29 12:35
閱讀 758·2019-08-28 18:22
閱讀 1934·2019-08-26 13:58
閱讀 1671·2019-08-26 10:39
閱讀 2677·2019-08-26 10:11