HTTP連線管理(1) – TCP Performance Cosiderations

本篇文章重點整理HTTP: The Definitive Guide一書的內容,主要著重在影響HTTP效能的因素。

The TCP connection setup handshake

當你要建立一個HTTP連線前必須要先建立一個TCP連線,確保彼此可以開始溝通和傳輸資料,這個過程稱為TCP Connection Handshaking(Syn, Syn-Ack, Ack),所有的HTTP programmer並不會接觸到這個過程,當建立新的TCP連線時,他們所看到的是一小段的延遲。因此當傳輸的資料量很小時,幾乎會有一半甚至更多的時間在建立TCP連線。

TCP’s delayed acknoledgment algorithm for piggybacked acknoledgements

當我們透過TCP傳送一個packet到另一端,必須要收到Ack,然而由於Ack很小(~40 bytes),為了避免浪費網路頻寬,多數的作業系統會有個TCP buffer來暫時保留這個Ack,等到有同方向的資料時再組成一個packet送出(piggyback), 但是HTTP的request-reply 模式降低了piggyback的機會,導致Ack會等待一段時間後(100~200 millis)才送出。這個設定會依據你的作業系統而有所不同,所以如果你要更改這個設定,請確保你知道你做的更動所帶來的可能影響,並且不會對其他的應用程式帶來副作用!

TCP slow-start congestion control

為了要避免大量的資料突然湧進網路造成塞車,TCP連線在建立初期會限制傳輸的速度,當TCP連線建立越久資料的傳輸速度就越快,這個現象稱為TCP slow-start。簡單來說,當一個packet順利地從A傳輸到B端,則接下來A可以送出兩個packet,如果兩個packet都成功送達,接下來可以送出4個packet。鑑於TCP slow-start的這個特性,所以HTTP允許你重複使用已經建立好的連線(persistence connection),來改善HTTP的效能。

Nagle’s algorithm for data aggregation and TCP_NODELAY

TCP允許應用程式傳輸任何大小的資料量,即是是1 byte!但是因為TCP包含了一些基本的flags和headers(~40 bytes),所以如果TCP傳輸一個較大的packet,則網路的效能可能因此而下降。

Nagle的演算法試圖把一堆的TCP資料打包起來成為一個packet後才送出。因此並不鼓勵你送出一個不是full-size packet (~ 1,500 bytes),只有當其他的傳輸的packet都已經被Ack了,Nagle的演算法才允許你送出一個不是full-size的packet。如果其他的packet還在網路中,則資料會先被緩衝起來。被緩衝起來的資料會等到傳輸中的packet被Ack了或是累積足夠的資料量後才送出一個full-size packet。
Nagle的演算法會造成兩個效能上的問題:
1.小量的HTTP資料可能沒辦法填滿一個packet,所以可能被延遲送出並且等待一些永遠不會出現的資料
2.Nagle的演算法當遇到disabled Ack設定時效果會很差。Nagle的演算法會緩衝即將送出的資料直到收到前一個packet的Ack,但是Ack可能會因為Delay-Ack演算法而被被延遲100~200 millis才送出,導致緩衝中的資料延後被送出。

※大部分的HTTP程式會透過設定TCP_NODELAY來取消Nagle的演算進而提昇效能,如果你這麼做請確保你一次送出夠大的資料量避免傳輸過多小片段資料在TCP網路中。

TIME_WAIT delays and port exhaustion

這個問題在做壓力測試或流量很大時才會發生,將另文描述

發佈留言