為什麼需要將服務器在地理位置上靠近用戶? 原因之一是獲得較低的延遲。 當您發送應儘快傳送的短數據突發時,這很有意義。 但是,大文件(例如視頻)呢? 接收第一個字節肯定會帶來延遲損失,但是在那之後難道不是一帆風順嗎?
通過TCP(例如HTTP)發送數據時,常見的誤解是帶寬與延遲無關。 但是,對於TCP,帶寬是延遲和時間的函數。 讓我們看看如何。
握手
在客戶端可以開始向服務器發送數據之前,它需要為TCP執行一次握手,為TLS執行一次握手。
TCP使用三向握手來創建新連接。
· 發送方選擇一個隨機生成的序列號" x",並將SYN數據包發送給接收方。
· 接收器遞增" x",選擇一個隨機生成的序列號" y",然後發回SYN / ACK數據包。
· 發送方增加序列號,並用ACK數據包和應用程序數據的第一個字節進行回覆。
TCP使用序列號來確保按順序傳送數據且沒有空洞。
握手會引入完整的往返,這取決於基礎網絡的延遲。 TLS握手也最多需要兩次往返。 在TLS連接打開之前,無法發送任何應用程序數據,這意味著在此之前您的帶寬出於所有目的和目的均為零。 往返時間越短,建立連接的速度就越快。
流量控制
流控制是一種退避機制,旨在防止發送方壓倒接收方。
接收器將等待應用程序處理的傳入TCP數據包存儲到接收緩衝區中。
每當接收方確認數據包時,接收方還將其大小發送回發送方。 如果發件人遵守協議,則應避免發送更多可能容納在收件人緩衝區中的數據。
此機制與應用程序級別的速率限制不太相似。 但是,TCP不是在API密鑰或IP地址上進行速率限制,而是在連接級別上進行速率限制。
發送方和接收方之間的往返時間(RTT)越短,發送方將其出站帶寬調整到接收方容量的速度就越快。
擁塞控制
TCP不僅可以防止接收器不堪重負,還可以防止淹沒底層網絡。
發送者如何找出底層網絡的可用帶寬是多少? 估計它的唯一方法是根據經驗進行測量。
這個想法是發送者維護一個所謂的"擁塞窗口"。 該窗口表示無需等待對方的確認就可以發送的未完成數據包的總數。 接收器窗口的大小限制了擁塞窗口的最大大小。 擁塞窗口越小,在任何給定時間可以傳輸的字節越少,並且佔用的帶寬越少。
建立新連接後,擁塞窗口的大小將設置為系統默認值。 然後,對於每個確認的數據包,該窗口的大小都會成倍增加。 這意味著建立連接後,我們無法立即使用網絡的全部容量。 同樣,往返時間越短,發件人就可以越快地開始利用基礎網絡的帶寬。
如果丟包怎麼辦? 當發件人通過超時檢測到錯過的確認時,就會啟動一種稱為"避免擁塞"的機制,從而減小擁塞窗口的大小。 從那時起,時間將窗口大小增加了一定數量,而超時又將窗口大小減少了一些。
如前所述,擁塞窗口的大小定義了無需等待確認即可發送的最大位數。 發件人需要等待完整的往返行程才能獲得確認。 因此,通過將擁塞窗口的大小除以往返時間,可以得到最大的理論帶寬:
這個簡單的方程式表明帶寬是等待時間的函數。 TCP會盡力優化窗口大小,因為它無法解決往返時間。 但是,這並不總是能產生最佳配置。
總之,擁塞控制是一種自適應機制,用於推斷網絡的基礎帶寬和擁塞。 類似的模式也可以應用於應用程序級別。 想一想當您在Netflix上觀看電影時會發生什麼。 開始模糊; 然後,它會穩定到合理的水平,直到出現打ic為止,然後質量再次變差。 應用於視頻流的這種機制稱為自適應比特率流。
記住這一點
如果您使用的是HTTP,那麼您將受基礎協議的約束。 如果您不知道香腸的製作方法,就無法獲得最佳性能。
突發請求受到冷啟動懲罰。 可能需要多次往返,才能發送帶有TCP和TLS握手的第一個字節。 而且由於擁塞控制的工作方式,往返時間越短,底層網絡的帶寬利用就越好。
關於此主題的所有書籍都已經寫好了,您可以做很多事情來壓縮每一盎司的帶寬。 但是,如果您必須記住關於TCP的一件事,那就這樣:
您發送數據的速度不能超過光速,但是您可以做的是使服務器離客戶端更近,並重新使用連接以避免冷啟動的代價。
(本文翻譯自Roberto Vitillo的文章《What every developer should know about TCP》,參考:https://medium.com/swlh/what-every-developer-should-know-about-tcp-755ece34f13b)