影響TCP連接吞吐量的致命因素:HOL
一、什么是HOL
HOL是Head of line blocking的意思,在互聯(lián)網(wǎng)領(lǐng)域,包括HTTP head of line blocking和 TCP head of line blocking。
1. HTTP Head of line blocking
Wikipedia對HTTP HOL的解釋如下:
雖然HTTP/2解決了HTTP/1.1的HOL問題,但由于是建立在TCP基礎(chǔ)上,所以仍然存在TCP層面的HOL問題。
2. TCP Head of line blocking
TCP HOL定義如下:
例如在TCP接收緩沖區(qū),請求的第一個數(shù)據(jù)包由于某種原因一直未到達,緩沖區(qū)里面的后續(xù)數(shù)據(jù)包就無法傳遞給上層應(yīng)用,只能處于等待中,直到第一個數(shù)據(jù)包過來,才能一起傳遞給上層應(yīng)用。
TCP HOL帶來的問題具有普遍性。只要利用TCP,就有這方面的問題,因此影響范圍非常廣泛。
二、案例分析
1. Network switches
上圖展示了網(wǎng)絡(luò)交換機中不同input隊列是如何因為HOL等待的。
第一個和第三個input隊列,都在競爭使用Output 4。如果交換機選擇傳遞第三個input隊列的數(shù)據(jù)包,那么第一個input隊列的數(shù)據(jù)包只能選擇等待。第一個input隊列中的序號3數(shù)據(jù)包因為HOL只能等待,雖然output 3是空閑的。
2. 單個連接 vs 多個連接實驗
下面是并發(fā)為1的吞吐量,為153.60 reqs/sec。


下面是并發(fā)為10的吞吐量,為145.08 reqs/sec。
這里10個并發(fā)比1個并發(fā)吞吐量還低,是因為測試環(huán)境是docker環(huán)境,硬件配置差所導(dǎo)致。
上面測試是在無丟包網(wǎng)絡(luò)環(huán)境下進行的,那么在網(wǎng)絡(luò)丟包情況下會怎么樣?
我們模擬丟包率1%的網(wǎng)絡(luò)環(huán)境。
并發(fā)為1的吞吐量下降為37.41 reqs/sec。
并發(fā)為10的吞吐量為132.20 reqs/sec。
我們發(fā)現(xiàn)在丟包情況下,多個并發(fā)效果更好。這是因為多個并發(fā)情況下,HOL blocking問題得到了一定的緩解,而單個連接,則因為HOL blocking問題顯得很明顯。
3. tcpcopy和intercept交互
很長一段時間內(nèi),tcpcopy和intercept的交互只用了一個連接。當測試壓力比較大的時候,網(wǎng)絡(luò)會惡化,很容易出現(xiàn)丟包或者來不及接收數(shù)據(jù)的狀況,從而導(dǎo)致大量信息被阻塞住。
后來為了解決單個連接導(dǎo)致HOL的問題,采用了多個連接,性能得到了極大提升。
4. Java netty游戲框架
下圖展示了一個Java netty框架。
一個線程既用來處理讀數(shù)據(jù),又用來寫數(shù)據(jù),線程一會兒忙于處理讀事件,一會兒處理寫事件。集中處理讀事件的時候,待寫的數(shù)據(jù)被阻塞了,而集中處理寫事件的時候,讀事件被阻塞了。壓力一大,延遲就會變得很大。
三、HOL blocking帶來的問題
四、總結(jié)
程序架構(gòu)中,盡量采用多個連接的方式來處理各種事件,否則很容易遇到TCP的HOL阻塞問題。