TCP
TCP連接
tcp/ip是全球計算機以及網絡設備都在使用的一種常見的分組交換網絡分層協議集,客戶端可以打開一條tcp/ip連接,連接到可能運行在世界各地的服務器應用程序,一旦連接建立起來了,在客戶端和服務器的計算機之間交換的報文就永遠不會丟失,受損或者失序。
TCP的可靠數據管道
HTTP連接實際上就是TCP連接以及使用規則,TCP連接是互聯網上的可靠連接。
TCP為HTTP提供了一條比較靠譜的比特傳輸管道,從TCP連接一段填入字節會從另一端以原有的順序,正確的表達出來。
TCP會按序,無差錯的承載HTTP數據。
TCP流是分段的,由IP分組傳送
TCP的數據是通過名為IP分組或者IP數據報的小數據塊來發送的,安全版本就是在HTTP和TCP之間插入了一個TLS或者SSL密碼加密層
HTTP要傳送一個報文的時候,會以流的形式講報文數據的內容通過一條打開的tcp連接按照時序傳輸。tcp收到數據流之后,會將數據流砍成叫做段的小數據塊,所有的這些工作都是由tcp ip軟件來處理的。程序員不會參與。
每個tcp段都是由ip分組承載,從一個ip地址發送到另一個ip地址的,每個ip分組包括
- 一個ip分組首部
- 一個TCP段首部
- 一個TCP數據塊
ip首部包含了源和目的ip地址,長度和其他一些標記。tcp段的首部包含了tcp端口號,tcp控制標記,用于將數據排序和完整性檢查的一些數字值。
保持tcp連接持續不斷的運行
在任意時間計算機都可以由幾條tcp連接處于被打開狀態,tcp是通過端口號來保持所有這些連接持續不斷的運行
tcp連接是通過4個值來識別的<源ip地址, 源端口號, 目的ip地址, 目的端口號>
兩條不同的tcp連接不能擁有4個完全相同的地址組件值。但是不同的部分組件可以有相同的值。
用tcp套接字編程
套接字api允許用戶創建tcp的端口數據結構,將這些端點與遠程服務器的tcp端點進行連接,對數據流進行讀寫。
tcp的api隱藏了所有網絡協議的握手細節,以及tcp數據流和ip分組的分段和重裝細節
一旦建立了連接,客戶端就會發送HTTP請求,服務器就會讀取請求,一旦服務器獲取了整條報文請求,就會對請求進行處理,執行所請求的動作,并將數據寫回客戶端,客戶端讀取數據,并對響應的數據進行處理
對tcp性能的考慮
HTTP緊挨著TCP,位于上層,所以HTTP事務的性能很大程序取決于底層tcp通道的性能。
HTTP事務的時延
建立TCP連接,以及傳輸請求和響應報文的時間相比,事務時間可能是很短的。除非客戶端和服務器超載,或者正在處理復雜的動態資源。狗則http就是由tcp網絡時延構成的。
HTTP事務的時延由以下幾種原因
- 客戶端首先需要根據URI確定出web服務器的ip地址和端口號,如果沒有對URI中的主機名進行訪問,通過DNS解析系統會將URI的主機名轉換為一個ip地址,這個可能需要花費數10s的時間。
- 接下來,客戶端會向服務器發送一條tcp連接請求,并等待服務器回送一個請求接受應答,每條tcp連接都會有連接建立時延,最多只有一二秒鐘,但是如果是數百個HTTP事務的話,會疊加上去。
- 一旦建立起來了連接,客戶端就會通過新建立的tcp管道來發送http請求,數據到達的時候,web服務器就會從tcp連接中讀取報文,對請求進行處理。
- web服務器回送回HTTP響應,這個也需要花費時間。
性能聚焦的區域
- tcp連接建立握手
- tcp慢啟動擁塞控制
- 數據聚集的Nagle算法
- 用于捎帶確認的tcp延遲確認算法
- TIME_WAIT時延和端口耗盡
tcp連接的握手時延
如果建立一條新的tcp連接,甚至是發送任意的數據之前,tcp軟件會交換一系列的ip分組,對連接的有關參數會進行溝通,如果連接只是用來傳輸少量的數據,這些交換過程就會降低http的性能
建立tcp的幾個步驟
- 建立tcp連接時,客戶端需要向服務器發送一個小的tcp分組,這個分組中有設置syn標記,表明是一個連接請求
- 如果服務器接受了請求,就會對參數進行計算,并向客戶端返回一個分組,這個分組中的syn和ack都被置位,說明連接已成功
- 客戶端向服務器回送一條確認信息,通知它連接已成功建立
小的HTTP事務可能會在TCP建立上花費50%
延遲確認
每個tcp段都會有一個小的序列號和數據完整性校驗和,每個段的接收者受到完整的段的時候,會像發送者會送小的確認分組,如果發送者沒有再指定的窗口時間內受到確認的信息,發送者就會認為分組被損壞和損毀,重新發送數據。
延遲算法為了增強確認報文找到通向傳輸數據分組的可能性。延遲確認算法會在一個特定的窗口時間中將輸出確認存放在緩存區中,以尋找能夠捎帶它的輸出數據分組,如果在這個時間段內沒有輸出分組,就將確認信息放在單獨的分組中去。如果沒有輸出分組,就會將確認信息放在單獨的分組中傳送。
HTTP具有雙峰特征的請求——應答行為,降低了捎帶信息的可能,延遲確認算法會引入相當大的時延。
tcp慢啟動
tcp會隨著時間提高傳輸的速度。用于防止因特網的突然過載和擁塞。
如果HTTP事務由大量的數據要發送,不能一次將所有的分組都發送出去,發送一個分組,等待確認,就可以發送兩個分組,每個分組必須被確認。
Nagle算法和TCP_NODELAY
如果tcp發送了大量含有少量數據的分組,網絡的性能就會嚴重的下降。 發送大量單字節分組的行為稱為“發送端傻窗口綜合癥”。這種行為效率很低、違反社會道德,而且可能會影響其他的因特網流量
Nagle算法鼓勵發送全尺寸的段,只有當所有其他分組都被確認之后,才會允許發送非全尺寸的分組。如果其他分組仍然在傳輸過程中,就將那部分數據緩存起來。只有當掛起分組被確認,或者緩存中積累了足夠發送一個全尺寸分組的數據時,才會將緩存的數據發送出去
缺點: 1. 小的HTTP報文可能無法填滿一個分組,可能會因為等待那些永遠不會到來的額外數據而產生時延
TCP_NODELAY:http應用在自己的棧中設計參數,禁用這個算法,提高性能。但是要確保在tcp中寫入大塊的數據
TIME_WAIT累積和端口耗盡
當某個TCP端點關閉TCP連接時,會在內存中維護一個小的控制塊,用來記錄最近所關閉連接的IP地址和端口號,這類信息維持2MSL時間。
TIME_WAIT狀態通常會持續2倍的最大報文段生存時間(2MSL),以確保在這段時間內不會創建具有相同地址和端口號的新連接。
當系統中存在大量的短連接時,每個連接在關閉后都會進入TIME_WAIT狀態,導致TIME_WAIT狀態的數量迅速增加。由于每個TCP連接都需要一個唯一的端口號,而端口資源是有限的,因此大量的TIME_WAIT狀態可能會導致端口資源耗盡,從而影響新的連接的建立。