流量削峰的由來
主要是還是來自于網際網路的業務場景,例如,馬上即将開始的春節火車票搶購,大量的使用者需要同一時間去搶購;以及大家熟知的阿裡雙11秒殺,短時間上億的使用者湧入,瞬間流量巨大(高并發),比如:200萬人準備在淩晨12:00準備搶購一件商品,但是商品的數量卻是有限的100-500件左右。
這樣真實能購買到該件商品的使用者也隻有幾百人左右, 但是從業務上來說,秒殺活動是希望更多的人來參與,也就是搶購之前希望有越來越多的人來看購買商品。
但是,在搶購時間達到後,使用者開始真正下單時,秒殺的伺服器後端卻不希望同時有幾百萬人同時發起搶購請求。
我們都知道伺服器的處理資源是有限的,是以出現峰值的時候,很容易導緻伺服器當機,使用者無法通路的情況出現。
線上上的秒殺等業務場景,也需要類似的解決方案,需要平安度過同時搶購帶來的流量峰值的問題,這就是流量削峰的由來。
實作方案
削峰從本質上來說就是更多地延緩使用者請求,以及層層過濾使用者的通路需求,遵從“最後落地到資料庫的請求數要盡量少”的原則。
消息隊列解決流量削峰問題
要對流量進行削峰,最容易想到的解決方案就是用消息隊列來緩沖瞬時流量,把同步的直接調用轉換成異步的間接推送,中間通過一個隊列在一端承接瞬時的流量洪峰,在另一端平滑地将消息推送出去。
消息隊列中間件主要解決應用耦合,異步消息, 流量削鋒等問題。常用消息隊列系統:目前在生産環境,使用較多的消息隊列有 ActiveMQ、RabbitMQ、 ZeroMQ、Kafka、MetaMQ、RocketMQ 等。
在這裡,消息隊列就像“水庫”一樣,攔蓄上遊的洪水,削減進入下遊河道的洪峰流量,進而達到減免洪水災害的目的。
流量削峰漏鬥:層層削峰
針對秒殺場景還有一種方法,就是對請求進行分層過濾,進而過濾掉一些無效的請求。
分層過濾其實就是采用“漏鬥”式設計來處理請求的,如下圖所示:
這樣就像漏鬥一樣,盡量把資料量和請求量一層一層地過濾和減少了。
1)分層過濾的核心思想
通過在不同的層次盡可能地過濾掉無效請求。
通過CDN過濾掉大量的圖檔,靜态資源的請求。
再通過類似Redis這樣的分布式緩存,過濾請求等就是典型的在上遊攔截讀請求。
2)分層過濾的基本原則
對寫資料進行基于時間的合理分片,過濾掉過期的失效請求。
對寫請求做限流保護,将超出系統承載能力的請求過濾掉。
涉及到的讀資料不做強一緻性校驗,減少因為一緻性校驗産生瓶頸的問題。
對寫資料進行強一緻性校驗,隻保留最後有效的資料。
最終,讓“漏鬥”最末端(資料庫)的才是有效請求。例如:當使用者真實達到訂單和支付的流程,這個是需要資料強一緻性的。
總結
1.對于秒殺這樣的高并發場景業務,最基本的原則就是将請求攔截在系統上遊,降低下遊壓力。如果不在前端攔截很可能造成資料庫(mysql、oracle等)讀寫鎖沖突,甚至導緻死鎖,最終還有可能出現雪崩等場景。
2.劃分好動靜資源,靜态資源使用CDN進行服務分發。
3.充分利用緩存(redis等):增加QPS,進而加大整個叢集的吞吐量。
4.高峰值流量是壓垮系統很重要的原因,是以需要Kafka等消息隊列在一端承接瞬時的流量洪峰,在另一端平滑地将消息推送出去。