1、什么是HOL
HOL是Head of line blocking的意思,在互聯網領域,包括HTTP head of line blocking和 TCP head of line blocking。
1.1 HTTP Head of line blocking
Wikipedia對HTTP HOL的解釋如下:
雖然HTTP/2解決了HTTP/1.1的HOL問題,但由于是建立在TCP基礎上,所以仍然存在TCP層面的HOL問題。
1.2%20TCP%20Head%20of%20line%20blocking
TCP%20HOL定義如下:
例如在TCP接收緩沖區,請求的第一個數據包由于某種原因一直未到達,緩沖區里面的后續數據包就無法傳遞給上層應用,只能處于等待中,直到第一個數據包過來,才能一起傳遞給上層應用。
TCP%20HOL帶來的問題具有普遍性。只要利用TCP,就有這方面的問題,因此影響范圍非常廣泛。
2、案例分析
2.1%20Network%20switches
上圖展示了網絡交換機中不同input隊列是如何因為HOL等待的。
第一個和第三個input隊列,都在競爭使用Output 4。如果交換機選擇傳遞第三個input隊列的數據包,那么第一個input隊列的數據包只能選擇等待。第一個input隊列中的序號3數據包因為HOL只能等待,雖然output 3是空閑的。
2.2 單個連接 vs 多個連接實驗
下面是并發為1的吞吐量,為153.60 reqs/sec。
下面是并發為10的吞吐量,為145.08 reqs/sec。
這里10個并發比1個并發吞吐量還低,是因為測試環境是Docker環境,硬件配置差所導致。
上面測試是在無丟包網絡環境下進行的,那么在網絡丟包情況下會怎么樣?
我們模擬丟包率1%的網絡環境。
并發為1的吞吐量下降為37.41 reqs/sec。
并發為10的吞吐量為132.20 reqs/sec。
我們發現在丟包情況下,多個并發效果更好。這是因為多個并發情況下,HOL blocking問題得到了一定的緩解,而單個連接,則因為HOL blocking問題顯得很明顯。
2.3 tcpcopy和intercept交互
很長一段時間內,tcpcopy和intercept的交互只用了一個連接。當測試壓力比較大的時候,網絡會惡化,很容易出現丟包或者來不及接收數據的狀況,從而導致大量信息被阻塞住。
后來為了解決單個連接導致HOL的問題,采用了多個連接,性能得到了極大提升。
2.4 JAVA netty游戲框架
下圖展示了一個Java netty框架。
一個線程既用來處理讀數據,又用來寫數據,線程一會兒忙于處理讀事件,一會兒處理寫事件。集中處理讀事件的時候,待寫的數據被阻塞了,而集中處理寫事件的時候,讀事件被阻塞了。壓力一大,延遲就會變得很大。
3、HOL blocking帶來的問題
4、總結
程序架構中,盡量采用多個連接的方式來處理各種事件,否則很容易遇到TCP的HOL阻塞問題。