限流能夠認爲服務降級的一種,限流就是限制系統的輸入和輸出流量已達到保護系統的目的。通常來講系統的吞吐量是能夠被測算的,爲了保證系統的穩定運行,一旦達到的須要限制的閾值,就須要限制流量並採起一些措施以完成限制流量的目的。好比:延遲處理,拒絕處理,或者部分拒絕處理等等。java
坐地鐵上班的同窗對於這張圖片是否是都不會陌生。
基本上在上下班的遲早高峯咱們就會發現進站的閘機會有一部分是關閉的。爲何地鐵站會關閉一部分閘機呢?這就是爲了限流。畢竟地鐵站就那麼大,可容納的人數也就那麼多。若是你們一股腦所有擠進地鐵站是否是又會發生踩踏事件什麼的。這是生活中的限流。還有咱們去景區玩,景區的門票是否是也是固定的,天天就賣那麼多張,賣完即止。限流是否是和咱們的生活也息息相關。程序員
開篇也有說到限流是爲了保證系統的穩定運行。假設咱們一個系統一小時之最多隻能處理10000個請求,可是一小時流量突增10倍,這突增的流量咱們若是不進行限制的話,任由它直接進入系統的話,是否是直接會把咱們的系統弄癱瘓,就沒法對外提供服務了。本人就曾經被這個所坑過,有一次把爬蟲開關攔截的開關給關掉了,忽然有一大波的爬蟲流量進入系統中,咱們也沒有把這些爬蟲請求進行攔截,而後一股腦的所有給轉發到下游系統裏面去了。下游系統直接就找上門來了,形成他們的服務發生大量的超時。好比地鐵早高峯的時候咱們若是不對地鐵站進行限流的話,你們是否是都會往地鐵站擠,而後再往地鐵裏面擠,擠不上都還要擠。會致使地鐵門都關不上,而後地鐵就開不走,會致使愈來愈多的人堵在地鐵站。而後最後就會致使整條地鐵線都阻塞了。上班就妥妥的遲到了(對於程序員說大多數應該是彈性制的因此也不存在遲到這一說法)。算法
這個是最最簡單粗暴的作法了,直接把請求直接拒絕掉。
好比早高峯坐地鐵的時候,直接讓進入1000我的,剩下多出來的人不讓坐地鐵了。直接把入站口給關閉了。數據庫
將系統的全部功能服務進行一個分級,當系統出現問題,須要緊急限流時,可將不是那麼重要的功能進行降級處理,中止服務,這樣能夠釋放出更多的資源供給核心功能的去用。
假設有一個功能新用戶註冊完,要給用戶發送多少優惠券。這時候服務降級的話就能夠直接把送券服務關掉,讓服務快速響應,提升系統處理能力。
應用到早高峯坐地鐵的時候好比在人民廣場這個大站點,處理不過來了那麼多人換乘,咱們是否是能夠直接地鐵一號線在人民廣場不停,直接到下一站在停,這時候通過人民廣場換乘的人就少多了。分佈式
把請求所有放入到隊列中,真正處理的話,就從隊列裏面依次去取,這樣的話流量比較大的狀況可能會致使處理不及時,會有必定的延時。雙十一零點咱們付款的時候,去查詢訂單的狀態是否是也會有必定的延時,不像在平時付完款訂單狀態就變成了付款狀態。ide
這個模式須要將用戶進行分類,經過預設的分類,讓系統優先處理須要高保障的用戶羣體,其它用戶羣的請求就會延遲處理或者直接不處理。咱們去銀行辦理業務的時候是否是也會常常須要排隊,可是是否是常常會VIP用戶、什麼白金卡用戶,直接不須要排隊,直接一上來就能夠辦理業務,還優先處理這些人的業務。是否是特羨慕這些人,哎 羨慕也沒辦法誰叫人家有錢咧。線程
這是最簡單的限流算法了,系統裏面維護一個計數器,來一個請求就加1,請求處理完成就減1,當計數器大於指定的閾值,就拒絕新的請求。是經過全局的總求數於設置的閾值來達到限流的目的。一般應用在池化技術上面好比:數據庫鏈接池、線程池等中應用。這種方式的話限流不是平均速率的。扛不住突增的流量。code
咱們能夠看到水是能夠持續流入漏桶裏面的,底部也是勻速的流出,若是流入的速率大於底部流出的速率,以及漏桶的水超過桶的大小就會發生益出。請求一通過漏桶的過濾,無論你請求有多少,速率有多快,我反正就這麼個速度處理。咱們平時坐地鐵的時候是否是也是這樣,無論你乘客有多少,反正就是隔5min發一趟車。那早高峯的時候你5min鍾一趟車根本就不夠用啊,上班的人太多啊,你須要加快速度處理啊,因此可能早高峯改成3min一趟,動態調整速率。blog
看圖的話是否是令牌桶和漏桶都差很少,只不過令牌桶新增了一個勻速生產令牌的中間人以恆定的速度往桶裏面放令牌,若是令牌的數量超過裏桶的限制的話,令牌就會溢出,這時候就直接捨棄多餘的令牌。每一個請求過來必須拿到桶裏面拿到了令牌才容許請求(拿令牌的速度是不限制的,這就意味着若是瞬間有大量的流量請求進來,能夠短期內拿到大量的令牌),拿不到令牌的話直接拒絕。這個令牌桶的思想是否是跟咱們java裏面的Semaphore 有點相似。Semaphore
是拿信號量,用完了就還回去。可是令牌桶的話,不須要還回去,由於令牌會定時的補充。令牌桶算法咱們能夠經過Google開源的guava包建立一個令牌桶算法的限流器。隊列