當前位置:
首頁 > 最新 > 簡單的流量控制系統

簡單的流量控制系統

流量控制概述

在一個後台系統中,流量控制屬於基礎組件的功能,其實,在很久之前的通訊時代,流量控制就已經非常成熟了,在路由器交換機上面幾乎都有全面的流量控制的解決方案,像QoS這類流量整形的方案,都已經是在網路模型的各個層來進行流量的控制和分發了,可以按照通道,按照埠,IP,MAC,業務類型等各個維度對流量進行整形和控制,比如讓語音類的這種高優先順序的流量優先通過,而視頻聊天這種丟了幾幀數據其實沒什麼影響的低優先順序流量慢點通過。對於流量控制,在中後台系統中,一般分成兩個類型吧,一種是對連接數進行控制,保證一個機器有可控的連接數,一種是對真實流量的控制,保證機器能通過的流量有多少。流量控制和緩存一樣,實際上是對後端的服務起到一個保護的作用,不至於把後端的服務擊穿,不同的地方在於緩存保護的主要是讀操作,如果用緩存來保護寫操作的話,也是一個非同步的過程,像下面這個圖一樣。

而流量控制主要保護的就是寫操作了,保證後端的服務別被寫請求給擊穿,目前我們之所以很少見到流量控制的服務了,主要因為大家優化方向已經朝其他兩個方向上來做了。

一是優化了後端的服務,把後端服務變成了一個可以動態擴展的集群,現在都是說要彈性擴展嘛,所以把優化放到後端伺服器上去了,讓後端的伺服器能夠承載更多的寫流量,流量控制的東西相比就少了,而且從用戶體驗上來說,後端伺服器能夠承載更大的流量也可以保證數據的實時性更好,不會產生數據的延遲,所以擴展後端的集群規模成了一個優化方向。就像下圖這樣,後端的DB變成了一個集群來保證寫規模的擴大。

另外一個優化方向就是引入了消息隊列這個東西,實際上消息隊列就是一個升級版本的流量控制系統,雖然它沒有用到流量控制的這些個演算法,但是它達到的目前和流控其實差不太多,效果還更好,所以現在一旦出現後端扛不住寫的情況,都在中間加上一個消息隊列來解決,一是解決了寫入流量的可控,二是還把系統給解耦了,一舉兩得。

正因為上面的兩個原因,現在關注流量控制的人變少了。但有時候,如果後端的服務不能抗住寫的壓力,並且也沒有足夠的資源去部署一個消息隊列的話(因為消息隊列的部署是需要單獨的伺服器的,還是有成本上的考慮),那麼做一個簡單的流控系統也基本能滿足要求。在本文中,基於連接的流量控制就不是我們討論的範圍了,那個比較簡單一點。

流控設計

我們所說的流量控制,大家比較了解的一般分成兩種演算法,一種是漏桶演算法,一種是令牌桶演算法,我們這裡並不去深究這兩種演算法的區別,這個可以在網上很容易找到兩種演算法的定義和演算法描述,這兩種流控策略都是來源於路由器的IP層流量控制的演算法,我們從另外一個角度來看看流控,我們只借用這些演算法的思想,從需求開始,自己一步一步設計一個流控系統。

流控需求

首先,拿到一個流量控制的需求,需求是入口流量是5MB/s,但是峰值流量是100MB/s,出口的流量要控制在50MB/s以內,數據還不能丟棄,如何來實現這個系統。

初步設計

第一感覺應該就是下圖這個樣子,中間有一個內存的FIFO隊列,寫入方不停的往這個隊列裡面寫入數據,而另一端不停的讀取這個FIFO,然後把流量分發到後端上去,這樣就完成了數據不能丟棄這個需求,很像前面的那個消息隊列,但是慢著,要是前端的寫入流量一直保持在峰值的話,那麼這內存也爆了,所以除了內存的FIFO以外,還需要一個文件的FIFO來保證在一直是峰值的情況下保證數據的不丟失,你要是問要是硬碟滿了怎麼辦,那我只能呵呵了,當然,也不是沒有解決辦法,把服務設計成多機模式嘛,這不在本文的討論範圍內。

總之,按照上圖的設計方法,基本可以滿足數據不丟的情況了,對於FIFO的實現方式,可以有很多種,一種是自己開鏈表,兩個指針一頭一尾,一邊寫一邊讀,如果兩邊都是多線程的話,鎖的設計需要特別注意,盡量減少鎖的消耗。還有如果是使用想golang這樣的帶channel的語言,那麼直接丟到channel裡面也行,不過這樣就是內存不太可控,如果某一個時間段上的數據包都特別大的話,容易造成整體內存的飆升,看具體場景和硬體資源吧,這裡就不在贅述了,那麼,接下來就考慮流控了。

流控控制器

既然需要流量控制,那麼就是發送端在發送數據的時候得知道我現在這個數據能不能發,能發的話可以全發出去還是只能發一部分,最簡單的辦法就是有個整體的流量控制器,每次發送端發送數據的時候都去詢問一下這裡流量控制器,現在有多少配額,我能用多少,結構圖如下圖所示,發送端去詢問流量控制器,然後拿到一個發送的配額,按照這個配額進行發送。

現在FIFO隊列也有了,流量控制器也有了,但是最關鍵的就是流量控制器如何工作的呢?接下來就要設計這個流量控制器了。

流控演算法

對於流控演算法的設計,因為是配額制的,所以我們首先得有一個配額的產生機制,比如需求裡面說的50MB/s,那就是每秒可以產生50MB的配額,這個簡單,你把配額看成一個池子,每秒往池子里加50MB就行了,一旦池子滿了,就不加了嘛,這裡說的是每秒50MB,實際上加的時候可以按照毫秒來,比如每10毫秒往池子裡面加0.5MB,這個用一個線程循環的線程就可以完成。

Quota=0 while(1){ sleep(10MS) ; Quota+=0.5;if(Quota>=50) }

如果是golang的話,也可以把這一部分交給channel來做,寫滿了就阻塞在channel上了,就像下面這樣:

QuotaChannel:=make([]int,100) for{ QuotaChannel

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 推酷 的精彩文章:

你拿到的請求地址還對嗎?
史玉柱:當年巨人的倒台是必然,因為我性格里的狂妄、不尊重經濟規律、不懂管理……
關於內容營銷,你需要知道的十點真相
你需要的 React Native 二維碼掃描組件
vuejs開發H5頁面總結

TAG:推酷 |

您可能感興趣

微機控制點火系統的工作原理與控制調整
工業機器人的控制系統講解
最簡單又穩定的電腦重裝系統方法
上燃安薩爾多機型 控制系統體系結構及硬體
一種僅靠「調節發動機推力」的備份飛行控制系統
強制關閉你的系統的內核模塊
電力系統發揮出色,制霸榜單
安卓系統怎麼就沒有蘋果系統的「流暢性」和「穩定性」?
一款簡單方便的系統重裝軟體
操作系統批量安裝
預填單系統操作手冊
電腦操作系統
工業控制系統安全雜談
基於數據流的網路監控系統
導彈是依靠自身動力裝置推進,由制導系統導引、控制其飛行路線並導向目標的武器
系統管理模式推測執行攻擊
工業控制系統概念及其安全屬性
單人飛行系統
利用手上穴位來調節你的運動系統、生殖系統
車載藍牙移動通信免提系統 的系統結構與產品特色