高併發下如何快速使用MQ實現緩衝流量,削峯填谷

爲什麼使用原因是?
服務之間的傳遞常用的調用就是直接調用(RPC框架)和消息MQ推送兩種,但是都有一個缺點,下游消息接收方無法控制到達自己的流量,如果調用方不限速,很有可能把下游壓垮。

 

背景信息

在實際應用中,收到的請求是沒有規律的。例如:某應用的處理請求的能力是每秒 10 個。在某一秒,突然到來了 30 個請求,而接下來兩秒,都沒有請求到達。在這種情況下,如果直接拒絕 20 個請求,應用在接下來的兩秒就會空閒。所以,需要把驟增的請求平均到一段時間內,讓系統負載保持在請求處理水位之內,同時儘可能地處理更多請求



peak shaving_1
上圖中,紅色的部分代表超出消息處理能力的部分。把紅色部分的消息平均到之後的空閒時間去處理,這樣既可以保證系統負載處在一個穩定的水位,又可以儘可能地處理更多消息。通過配置流控規則,可以達到消息勻速處理的效果。


舉個例子,秒殺業務:

上游發起下單操作

下游完成秒殺業務邏輯(庫存檢查,庫存凍結,餘額檢查,餘額凍結,訂單生成,餘額扣減,庫存扣減,生成流水,餘額解凍,庫存解凍等等)

上游下單業務簡單,每秒發起了10000個請求,下游秒殺業務複雜,每秒只能處理2000個請求,很有可能上游不限速的下單,導致下游系統被壓垮,引發雪崩。

 

爲了避免雪崩,常見的優化方案有兩種:

1)業務上游隊列緩衝,限速發送

2)業務下游隊列緩衝,限速執行


1、業務下游隊列緩衝,限速執行第一種方法

問:MQ怎麼改能緩衝流量?

答:由MQ-server推模式(常用模式),升級爲MQ-client拉模式。

MQ-client根據自己的處理能力,每隔一定時間,或者每次拉取若干條消息,實施流控,達到保護自身的效果。並且這是MQ提供的通用功能,無需上下游修改代碼。

 

問:如果上游發送流量過大,MQ提供拉模式確實可以起到下游自我保護的作用,會不會導致消息在MQ中堆積(提升整體吞吐量)?

答:下游MQ-client拉取消息,消息接收方能夠批量獲取消息,需要下游消息接收方進行優化,方能夠提升整體吞吐量,例如:批量寫。


rocketMQ的拉取模式代碼  https://blog.csdn.net/zhaohongfei_358/article/details/101457563

rabbitMQ拉取模式代碼 https://my.oschina.net/u/3959468/blog/2979069


2、業務下游隊列緩衝,限速執行第二種方法

rabbitMQ 提供了一種 QOS (服務質量保證)功能,即在非自動確認消息的前提下,如果一定數目的消息(通過基於 consume 或者 channel 設置 QOS 的值)未被確認前,不進行消費新的消息。關鍵代碼就是在聲明消費者代碼裏面的

void basicQos(unit prefetchSize , ushort prefetchCount, bool global )
  1. prefetchSize:0

  2. prefetchCount:會告訴 RabbitMQ 不要同時給一個消費者推送多於 N 個消息,即一旦有 N 個消息還沒有 ack,則該 consumer 將 block 掉,直到有消息 ack

  3. global:true、false 是否將上面設置應用於 channel,簡單點說,就是上面限制是 channel 級別的還是 consumer 級別

備註:prefetchSize 和 global 這兩項,rabbitmq 沒有實現,暫且不研究。特別注意一點,prefetchCount 在 no_ask=false 的情況下才生效,即在自動應答的情況下這兩個值是不生效的。


具體可以學習:https://www.jianshu.com/p/36b9c367d440

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章