java程式設計師菜鳥進階(七) HTTP權威指南 之HTTP連線管理及對TCP效能的考慮
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
在上一篇部落格中(《HTTP權威指南》之HTTP相關概念詳解)我們簡單對HTTP相關的基本概念做了一些簡單的瞭解,但未對HTTP
'
TCP流是通過分段、由IP分組傳送
TCP資料是通過IP分組的小資料塊來發送的。這樣就形成了“HTTP OVER TCP OVER IP”的資料傳輸方式。http就是這種傳輸方式的最頂層。HTTP的安全版本HTTPS就是在HTTP和TCP之間插入了一個密碼和加密層(成為TLS或SSL),TCP在傳輸資料時會以流的形式從一個開啟的TCP連線中傳輸,在傳輸的過程中TCP流會分成一個個小資料庫分不到各個IP分組裡面。每個IP分組都包括:
l 一個IP分組收首部(包含源和目的IP
l 一個TCP段首部((包含TCP埠號、控制標誌等)
l 一個TCP資料塊
保持TCP連線的正確性
如何保證資料傳輸過程中的正確性是TCP連線的一個首要任務,世界上那麼多的計算機,怎麼樣才能正確的從源計算機的某個源應用傳輸到目的計算機的目的應用。TCP就是通過IP和埠號來保證這一連線的正確性的。TCP通過4個值來識別:
<源IP地址 源埠號 目的IP地址 目的埠號>
TCP資料流中的IP分組中小資料塊形式:
TCP套接字程式設計
作業系統提供了一套操作TCP連線的工具,為了簡單明瞭起見,我們來直接看一下TCP的程式設計介面。主要是Java的一些常用API
1.socket(family,type)
建立套接字物件,family=socket.AF_INET,type=socket.SOCK_STREAM(TCP)/socket.SOCK_DGRAM(UDP)
2.s.bind((host,port))
繫結套接字s以接收來自主機host在埠號port上的連線。host可以是空字串(''),表示接受來自任何主機的連線。
3.s.listen(maxpending)
監聽到該套接字的連線嘗試,任何時候允許最多maxpending個排隊的連線嘗試。
4.s.accept()
s必須是TCP型別,接收一個連線請求並返回一個數據對(s1, (ipaddress, port))。s1是一個新連線的套接字。呼叫之前必須已經呼叫了s.bind和s.listen方法。
5.s.recv(bufsize)
從套接字接收最多bufsize個位元組的資料,並返回一個由接收的資料組成的字串。
6.s.sendall(string)
在套接字上按位元組傳送string字串,該方法將會阻塞,直到所有的位元組都被髮送。
7.s.close()
關閉套接字。
8.s.recvfrom(bufsize)
從套接字接收最多bufsize個位元組的資料,並返回一個元組(data, (ipaddr, port))。在使用UDP時很有用,可以接收來自多個傳送方的資料。
9.s.sendto(string,(host,port))
在套接字上將string字串按照位元組傳送到目的host和port上,並返回傳送的位元組數n。對UDP很有用,可以將資料傳送到多個目的地。
10.s.connect((host, port))
將套接字s連線到給定host和port指定的伺服器上。
對TCP效能的考慮
HTTP在TCP的上一層,位於應用層,對HTTP效能的考慮無非就是對TCP效能的考慮,在瞭解了TCP的效能優化之後就可以很好的理解HTTP的連線優化的相關特性了。這樣我們在做應用開發的過程中就可以設計實現一些高效能的HTTP應用程式了。
1.HTTP事務時的延時
在一個HTTP事務的整個過程中的延時可以描述出TCP效能瓶頸的問題所在。下面我們從一個圖中看一下TCP效能問題所在之處
從上圖可以看出整個HTTP事務的延時主要有以下:
1).解析時延 DNS解析與DNS快取
客戶端首先需要根據URL確定Web伺服器的IP地址和埠號,如果最近沒有對URL中的主機名進行訪問,那麼DNS將URL中的主機名轉換為IP地址可能會花費數十秒的時間。如果是近期訪問過的主機名,那麼在HTTP客戶端的DNS快取中,就會儲存該主機名對應的IP地址。
2).連線時延 TCP連線的建立
接下來,客戶端會向伺服器傳送一條TCP連線請求,並等待伺服器回送一個請求接受應答。每條新的TCP連線都會有連線新建時延,這個時間雖然很短,但是如果一次性新建多條TCP連線,那麼這個時延疊加起來就很長了。
3).傳輸時延 HTTP請求傳送 HTTP響應返回
一旦連線建立起來之後,客戶端就會通過新建的TCP通道來發送HTTP請求,資料到達時,web伺服器會從TCP連結中讀取請求報文,並處理。因特網傳輸請求報文以及伺服器處理請求報文都需要時間
4).處理時延 HTTP報文處理
伺服器會回送HTTP響應,這也需要花費時間。
2.延遲確認機制:保證資料傳輸的成功
每個TCP段都有一個序列號和一個數據完整性校驗和。每個段的接收者收到完好的段時,都會向傳送者回送一個小的確認分組。如果傳送者沒有在指定的視窗時間內收到確認資訊,傳送者就會認為分組已被破壞或損毀,並重發資料。
由於確認報文很小,所以TCP允許伺服器在發往客戶端的或者是客戶端發往伺服器的資料分組中隊其進行“捎帶”,將返回的確認資訊和輸出的資料分組結合在一起,更有效地利用網路。
為了增加確認報文找到同向傳輸資料分組的可能性,很多TCP棧都實現了一種“延遲確認”的演算法。延遲確認演算法會在一個特定的視窗時間愛你(通常是100~200ms)內將輸出確認放在緩衝區中,以尋找能夠捎帶它的輸出分組。如果在時間段內沒有輸出分數符合條件,那麼確認資訊就放到單獨的分組中進行傳送。
3.TCP網路延時分析
①.TCP連線的握手時延
建立一條新的TCP連線時,甚至是在傳送任意資料錢,TCP軟體之間會交換一系列的IP分組,對連線的有關引數進行溝通。如果連線只用來傳送少量的資料,這些交換過程就會嚴重降低HTTP的效能。
TCP握手需要經過以下幾個步驟:
1) 請求新的TCP連線時,客戶端要伺服器傳送一個小的TCP分組,這個分組中設定了一個特殊的SYN標記,說明這是一個連線請求。
2) 如果伺服器接收了連線,就會對一些連線引數進行計算,並向客戶端回送一個TCP分組,這個分組中的SYN和ACK標記都被置位,說明連線請求已被接受
3) 最後,客戶端向伺服器回送一條確認資訊,通知它連線已成功建立。現代的TCP棧都允許客戶端在這個確認分組中傳送資料
通常HTTP事務的交換資料量都不會太多,所以SYN/SYN+ACK握手就佔用了大部分的時間。一般的小的HTTP事務可能會在TCP建立上花費50%,或更多的時間
改進方法:重用連線
②.TCP慢啟動
TCP連線會隨著時間進行自我調諧,起初會限制連線的最大速度,如果資料成功傳輸,會隨著時間的推移提高傳輸的速度。這種調諧被稱為TCP慢啟動,用於防止因特網的突然過載和擁塞。
TCP慢啟動限制了一個TCP端點在任意時刻可以傳輸的分組數。簡單來說,每成功接收一個分組,傳送端就有了傳送另外兩個分組的許可權。當一個HTTP事務由大量資料要傳送的時候,是不能一次性將所有分組都發送出去的,必須先發送一個分組,等待確認,然後可以傳送兩個分組,每個分組都必須被確認,這樣就可以傳送4個分組了,一次類推。這種方法被稱為“開啟擁塞視窗”。
改進方法:持久連線
③.用於捎帶確認的TCP延遲確認
因特網無法確保可靠的分組傳輸,TCP協議實現自身的確認機制來保值資料的成功傳輸由於確認報文較小,TCP允許將返回的確認資訊與同向的輸出資料分組一起進行'捎帶',而為了增加捎帶概率採用延遲確認演算法。 HTTP的雙峰特徵-請求應答行為降低了捎帶資訊的可能性,通常,延遲演算法會導致一定的時延
④.資料聚集的Nagle演算法
TCP傳送大量包含資料的分組,會嚴重影響網路效能。Nagle演算法試圖在傳送分組之前,繫結大量TCP資料,鼓勵傳送全尺寸的段,將資料快取直至其他分組都被確認或者快取中已足夠全尺寸的段才會傳送。這樣就 引入了一些效能問題
1 小的HTTP報文可能無法填滿一個分組,可能會因為等待不會到來的資料產生時延
2 與延遲確認演算法互動存在問題。Nagle演算法阻止資料傳送,直到有確認分組抵達,但確認分組自身會被延遲確認演算法延遲,因為它在等待捎帶它的資料包
⑤.TIME_WAIT累積與埠耗盡
當某個TCP短點關閉TCP連線時,會在記憶體中維護一個小的控制塊,用來記錄所關閉的連線的IP地址和埠號。這個資料塊通常只能存在一個小時間段。這個演算法可以防止在短時間內建立、關閉具有相同IP和埠號的連線。
TIME_WAIT的作用:允許老的重複分組在網路中消失,防止最後ACK的丟失可靠地實現TCP全雙工通訊的終止
TCP連線四要素<源IP,源埠,目的IP,目的埠>,在一個客戶端和一臺伺服器的情況下,其中三個都是固定的,只有源埠可以改變,客戶端每次連線都會獲得新的源埠,以實現連線唯一性
由於源埠的數量有限,而且在2MSL時間內連線無法重用,伺服器連線率就會受限
解決辦法:可以增加客服端負載生成器的數量,或者確保客戶端和伺服器端在使用幾個虛擬IP地址以增加更多的連線組合。