前面的兩篇文章《談談網絡通訊中的 ACK、NACK 和 REX》和《談談網絡通訊中的 FEC 基礎》介紹了網絡通訊中的丟包重傳和 FEC 的相關理論和方法,他們都是在網絡發生丟包的狀況下的補救措施,本文則往前進一步,介紹下如何經過流量整形技術,儘量地避免網絡發生丟包。算法
從堵車提及緩存
堵車的緣由有不少種,咱們先聊聊圖中的這種:假設某公路是 3 股道,也就是說,每時刻能同時進入該公路的車輛並行是 3 輛,那麼,若是某一時間段,同時試圖進入該公路的車輛超過 3 輛,則必然會出現因爲公路的承載能力不夠帶來的 「堵車」。微信
網絡傳輸也相似,假設網絡帶寬是 2Mbps,若是在每秒硬塞給網絡的數據包 > 2Mbps,網絡通道也會受不了。不過它的表現形式與公路不同的地方在於:超出網絡承載能力的數據包,可能會被網卡/路由器/交換機給丟掉,即咱們常說的丟包(loss)。網絡
對於網絡傳輸而言,丟包帶來的成本是很高的,由於一些重要的數據包丟失後,是須要 「重傳」 的,而 「重傳」 太多,來回反覆會增長了數據傳輸的延時,也會進一步惡化網絡負荷,最終極大地下降了傳輸的效率。app
所以,咱們須要從根本上儘量地減小 「丟包」 的產生,簡單來講,就是控制單位時間內送入網絡傳輸的數據量,儘可能平滑且不要超過網絡帶寬承載能力。ide
控制對象ui
既然要控制送入網絡傳輸的數據量,就得先找到數據是怎麼產生的,又是在經過哪一個環節送入到網絡的。編碼
如圖,音視頻傳輸的數據 「源頭」 ,無外乎就是本地的音視頻文件、麥克風採集的音頻流、攝像頭採集的視頻流、桌面採集到的屏幕流等,它們通過編碼壓縮和封包處理,而後通過 「發送模塊」 送入到網絡中。spa
設置和修改採集的配置(如:分辨率、幀率)、編碼器的配置(如:GOP 間隔、碼率)等,是能夠減小實時產生的總數據量的,可是數據的產生並非 「平滑」 的,特別是視頻流/屏幕流,畫面的突變,會帶來數據量的突變,所以,送入到 「發送模塊」 的數據量,也並不會老是 「平滑」 的。3d
從上面的 「堵車」 理論,爲了不丟包,咱們須要儘量地將數據 「平滑」 地送入網絡中,所以,「流量整形」 在此派上了用場,它做用於 「發送模塊」,目標是調整數據傳輸的平均速率,防止突發性的流量暴增致使網絡擁塞和丟包。
流量整形
如何平輸入和輸出,一個最容易想到方法,就是增長 「緩衝」,讓輸入的數據先進入 「緩衝區」 ,而後用恆定的 「速率」 從緩衝區取數據輸出。這種方法稱之爲 「漏桶算法」。
漏桶算法(Leaky Bucket)
如圖,使用一個 packet buffer(漏桶),把全部輸入的 packet 緩存起來。
設置一個目標的輸出碼率(好比:3Mbps),固定的時間間隔(好比:10ms),讀取 packet buffer(漏桶)中固定數量的 packet(如:3Mbit * 10ms / 1000 = 0.03Mbit)進行網絡發送。注:若是某時刻緩衝區沒有數據,則不用發送了。
漏桶算法的缺點
漏桶算法有一個明顯的缺點,由於很是精準的網絡帶寬沒法預判,那麼假設你設置了一個比較小的目標碼率(如 3Mbps),可能小於真實的網絡帶寬(如 10Mbps),這時,若是業務上產生了一些突發的流量,真實的網絡帶寬本能夠容許更快地完成發送,但通過了漏桶算法後,依然會以恆定的目標碼率慢慢地發送。因此說,漏桶算法沒法充分用滿網絡資源來下降傳輸延時。
解決方案有 2 個:
先慢啓動,而後將漏桶的目標碼率持續上探,直到出現網絡惡化(如:丟包增多)後再降下來,如此反覆,維持一個動態平衡,使得漏桶算法的目標碼率持續無限逼近網絡的承載能力
改進漏桶算法,容許其在執行過程當中,偶爾出現一些超過預設平均值的突發傳輸能力,用於應對業務上的流量突發,即:令牌桶算法
令牌桶算法(Token Bucket)
令牌桶算法在漏桶算法基礎上,提出一個改進,就是新增了 「令牌」 和 「令牌桶」。
「令牌」 表明着容許傳輸的字節數量,咱們以固定的時間間隔(好比:10ms)產生並送入 「令牌」 到 「令牌桶」,「令牌桶」 設置一個 「令牌」 數量上限(滿了沒有消耗就丟掉新增的令牌),所以,一次傳輸最大的容許突增的字節數 = M x B
發送模塊,以固定 t ms 的時間間隔去讀取 packet buffer,讀取的字節數 X 必須接近但小於等於當前 「令牌桶」 中容許傳輸的字節數(即:「令牌桶」 裏剩餘的 「令牌個數」 x B)。而且,傳輸完了多少字節,則刪除掉 「令牌桶」 裏對應個數的 「令牌」。
這種方法解決突發流量的關鍵點在哪呢 ?
在於 「令牌」 是能夠積累的,可能緩衝區在前 N ms 都沒有突發的數據,這時,「令牌」 依然在產生,而且被積累在了 「令牌桶」,一旦緩衝區突增了大量的數據,則能夠在短期內快速消費掉。固然,爲了防止突破網絡承載能力致使丟包,「令牌桶」 的最大 「令牌數量」 也相應作了一些限制。
小結
關於網絡通訊中的流量整形就簡單介紹到這裏了,「漏桶算法」 和 「令牌桶算法」 其實在不少的地方都有使用,好比服務端的限流降級,好比音視頻的平滑丟幀等等,固然,也還有一些基於這些算法的各類改進策略,這裏就不一一介紹了,歡迎你們來信 lujun.hust@gmail.com 交流,另外,也歡迎你們關注個人新浪微博 @盧_俊 或者 微信公衆號 @Jhuster 獲取最新的文章和資訊。