概述
作為網際網路時代偉大發明的TCP/IP技術可以說對當今時代產生了深刻的影響。經過近一個月的學習摸索,基本清楚了TCP/IP的面貌。由於TCP/IP在OS中位於核心態,很多細節其實使用者無法感知,所以自己對於TCP/IP會有一些疑惑。關於其中幾個點經過查閱一些書籍、部落格並結合自己的一些理解,在此整理精煉成帖。
注: 本文首發於 My 公眾號 CodeSheep ,可 長按 或 掃描 下面的 小心心 來訂閱 ↓ ↓ ↓
疑惑1 — 關於擁塞
疑惑一: 無論是滿啟動還是擁塞避免階段,擁塞視窗都在增加,理論上一定會碰到擁塞點,為什麼平時感覺不到擁塞呢?
看了很多書和文獻以後可能的解答如下:
-
1、OS中對接收視窗的最大設定多年未動,如windows在不啟用“TCP Window Option”情況下,最大接收視窗僅64KB。然而網路進步,很多環境的擁塞點遠在64kb以上,即傳送視窗永遠觸碰不到擁塞點
-
2、很多應用場景是互動式小資料交換,如聊天等,不會有擁塞的可能
-
3、有些應用在傳輸資料時採用同步方式,可能需要的視窗非常小(如採用了同步方式的NFS寫操作,每發一個寫請求就停下來等回覆,而一個寫請求可能僅有4kb)
-
4、即便偶爾擁塞,持續時間也不足以長到能感受出來,除非抓包看包交換細節
疑惑2 — 關於超時重傳
疑惑二: 關於超時重傳後的ssthresh設定問題的爭議
-
1、Richard Stevens在《TCP/IP詳解》中把臨界視窗值定為上次發生擁塞時的傳送視窗的一半
-
2、RFC5681則認為應是發生擁塞時未被確認的資料量的1/2(又稱FlightSize),且不小於2MSS
-
3、Westwood/Westwood+演算法則這樣認為:先推算出有多少包已被送達到接收方(可根據收方迴應的ACK來推算),從而精確地估算髮生擁塞時的頻寬,最後再依據頻寬來確認新的擁塞視窗
-
4、Vegas演算法則這樣認為:引入全新的概念,摒棄之前的在丟包後才調節擁塞視窗的做法。其通過監控網路狀態來調整發包速度,實現“真正的擁塞避免”。當網路良好時,RTT較穩定,此時可以增加擁塞視窗;當網路繁忙時,RTT增加,此時減小擁塞視窗
-
5、Compound演算法這樣認為:同時維持兩個擁塞視窗,一個類似於Vegas,另一個類似於RFC5681,真正起作用的是兩者之和(Win7上其預設關閉)
-
6、BIC演算法/CUBIC演算法 分別是linux2.6.18和linux 2.6.19所採用,目前尚未研究
關於TCP/IP的幾點精煉總結:
-
(1)當無擁塞時,傳送視窗越大,效能越好。∴在頻寬沒有限制的情況下,應儘量增加接受視窗,比如啟用Scale Option
-
(2)若經常發生擁塞,則限制傳送視窗反而可以提高效能,∵即便萬分之一的重傳對效能的影響都非常大。很多OS上可通過限制接收視窗的方法來↓傳送視窗
-
(3)超時重傳對於效能影響最大,∵RTO時間內未傳輸任何資料,而Cwnd會被設成1MSS,應儘量避免
-
(4)快速重傳對效能影響小一些,∵無等待時間,且Cwnd減幅不大
-
(5)SACK和NewReno有利於增加重傳效率,增加傳輸效能
-
(6)丟包對極小檔案的影響比打檔案嚴重。深層原因是因為讀寫一個小檔案需要的包數很少,∴丟包時往往湊不滿三個Dup ACK,只能等待超時重傳;而大檔案有較大可能觸發快速重傳
後記
作者更多的SpringBt實踐文章在此:
- Spring Boot應用監控實戰
- SpringBoot應用部署於外接Tomcat容器
- ElasticSearch搜尋引擎在SpringBt中的實踐
- 初探Kotlin+SpringBoot聯合程式設計
- Spring Boot日誌框架實踐
- SpringBoot優雅編碼之:Lombok加持
如果有興趣,也可以抽點時間看看作者一些關於容器化、微服務化方面的文章:
- 利用K8S技術棧打造個人私有云 連載文章
- 從一份配置清單詳解Nginx伺服器配置
- Docker容器視覺化監控中心搭建
- 利用ELK搭建Docker容器化應用日誌中心
- RPC框架實踐之:Apache Thrift
- RPC框架實踐之:Google gRPC
- 微服務呼叫鏈追蹤中心搭建
- Docker容器跨主機通訊
- Docker Swarm叢集初探
- 高效編寫Dockerfile的幾條準則