開放平臺的限流通常都是怎麼實現的?

架構擺渡人 發表於 2021-10-23

開放平臺,我相信大家並不陌生。當需要把一個產品本身的一些功能開放出去,可以讓三方開發者接入和使用,這就是開放平臺做的事情。

為什麼我們能用微信登入很多其他的應用,這就是因為這些應用通過接入微信開放平臺提供的能力實現了授權登入。

開放平臺的限流通常都是怎麼實現的?

開放平臺流控需求分析

對於開放平臺來說,有一個功能是必須要有的,那就是API的流控。

對於每一個接入開放平臺的應用,都會分配一個Appkey,這個Appkey下面會關聯你申請了哪些API。然後接入的API有些是不限量,可以一直呼叫。有些是需要申請呼叫包,比如一天10萬次的呼叫量。

除了總量的限制,還有對頻率的限制。比如每秒每個API呼叫頻率的限制,每秒每個Appkey呼叫頻率的限制。

要實現這些流控的功能,最好的方式就是已經有一個流量治理平臺,裡面提供了限流的功能。像開放平臺這種還不屬於普通的系統限流,有點偏業務限流了,因為有具體的數量指標。

技術選型

這也就是前面文章裡面跟大家講什麼時候要自研,什麼時候可以直接用開源。當需求無法滿足,就只能自研了。

自研可以在開源的基礎上開發,增加業務限流的功能,支援租戶的功能,可以多租戶接入。支援按Appkey時間內的總量限流,支援API時間內的數量限流。

如果沒有現成的治理平臺可以接入,那麼就需要業務方自己進行開發。自己開發一般都會使用MySQL+Redis去實現。

實現原理

MySQL用於儲存基本配置資訊,比如Appkey對應的流控資訊,API對應的流控資訊。

Redis用於數量扣減提高效能使用,使用這個方案必然會帶來一個資料一致性的問題,就是MySQL裡的資料如何跟Redis保持一致。

為什麼要用Redis?

假設不用Redis也就意味著每次呼叫後都需要更新MySQL裡面的呼叫次數。在高併發的情況下,效能肯定是需要優先考慮的問題。

用Redis還是為了扛高併發,而且這個業務場景也不復雜,就一個計數而已,Redis本身也支援原子操作。

Redis只是用來輔助使用的,並不是作為業務資料的儲存系統。所以這裡就涉及到資料一致性的問題。

如何保持一致?

這裡我們再思考下,是否需要強一致性?

不需要,而且這個場景也不好做。所以只需要保證最終一致即可。

對於計數資訊,可以採取提前同步到Redis中,也可以採用延遲載入的方式。比如對某個Appkey下的某個API進行計數,key可以這樣設計 Appkey:API ,過期時間就是你要限制的時間段,比如按天來限制。

這裡需要有個定時同步Redis裡面的計數資訊到MySQL裡面的任務,時間間隔可以自行設定。假設Redis沒做持久化,重啟後資料丟失,這個時候會從MySQL裡面查出計數資訊進行初始化,如果你同步間隔是10分鐘一次,那麼只會有這10分鐘的呼叫次數丟失。

開放平臺的限流通常都是怎麼實現的?

我認為對於一般開放平臺來說,丟了一些計數資訊沒啥大問題,無非就是讓三方多呼叫一些數量的介面。但是具體業務具體分析,如果你們的API是按次計費的,那麼本方案可能不適合,涉及到錢的還是得強一致。

開放平臺的限流通常都是怎麼實現的?

單機還是叢集?

這個話題,前面的文章《流量治理神器-Sentinel的限流模式,選單機還是叢集?》裡面我們也聊到過。

那麼在開放平臺的這個業務場景下,毫無疑問的是要選擇叢集限流。首先它是一個業務場景的限流,有明確的限流指標,單機限流沒有全域性的儲存,無法反饋本身的結果給其他服務,就會導致業務結果不正確。