某天接到一線工程師反饋,用戶在登錄和使用某臺server的遠程桌面過程中延遲非常大,而連接其他的server正常。一線工程師已經做了以下嘗試:
1 使用client去ping server,沒有丟包,返回延遲比較小;
2 更換server至交換機的物理鏈路;
3 更換上行交換機;
一線工程師懷疑是server端的問題,但無法證明自己的推測,陷入了"我"為什么是"我"的死鎖,甩鍋也是需要強力證據來支撐的。一切展示給我們的故障現象,一定都隱藏在底層的錯誤積累。
一線工程師在Client端的匯聚交換機做了端口鏡像,從Client端(A:172.16.26.107)分別mstsc正常Server(B:172.16.4.26)和非正常Server(C:172.16.0.105),并使用wireshark抓包。
說到wireshark說段有趣的事,wireshark的開發者在分析和排查網絡的故障的時候,最初使用sniffer,后來sniffer收費了,換成我們可能第一反應是去"破解",但是開發者有版權意識:)自己開發并開源至今,當然如果對于英文不好,可以使用科來(基于wireshark內核)等國產的軟件。
分析:1 SYN ---SYN,ACK---ACK,通過time的時間戳能看的出響應時間都很短,在0.001S左右,印證了網絡質量沒有問題。
ServerC抓包
serverB抓包
2 在SYN,ACK時,C并沒有攜帶WS(windows scale),導致在三次握手協商后,滑動窗口為分別為:64240,525568(Calculated windows size = windows size *Window size scaling factor)。其實到這里基本可以判斷出故障的原因了:C由于沒有開啟Window scale,導致tcp協商時無法自動調節CWS,導致在交互過程中需要大量的ACK,影響了整體相應時間。我們對比以下用戶認證的過程也可以看得出,B只需要3次交互,而C需要6次:
ServerB用戶認證
ServerC用戶認證
問題反饋給系統工程師,通過修改相應的參數,msrdp訪問緩慢故障解決。
以下簡單介紹本次用到的tcp三次握手中的幾個參數:
1 TCP ACK的時候默認最大64240,我們姑且不扣除ip和tcp頭部的20+20開銷,那么這個值應該是65535=2^16,也就是每個窗口16bit,最大64k的速度,但由于現在網絡帶寬的大幅提升不足以支撐目前的需求,因此設計了options位的window scale來放大,由TCP發起端攜帶,如果發起端未攜帶,則被請求段不會攜帶該option位,本次是8=2^3,2^8=256倍:
window scale
2 Server在SYN+ACK同理如上:
serverB window scale
3 Ack,Client端最終協商出滑動窗口:2053*256=525568遠大于本次故障的64420;
ACK window scale
如大家對抓包并使用wireshark或者科來分析故障,可留言關注,分享更多案例和技巧。