限流冪等框架

限流和冪等框架設計和使用說明

1. 背景介紹

1.1 限流

        在早期的計算機領域,限流技術(time limiting)被用作控制網絡接口收發通信數據的速率。 可以用來優化性能,減少延遲和提高帶寬等。 現在在互聯網領域,也借鑑了這個概念, 用來爲服務控制請求的速率, 如果雙十一的限流, 12306的搶票等。限流就是限制流量,就像你寬帶包了1個G的流量,用完了就沒了。限流的目的是通過對併發訪問/請求進行限速或者一個時間窗口內的的請求進行限速來保護系統,一旦達到限制速率則可以拒絕服務(定向到錯誤頁或告知資源沒有了)、排隊或等待(比如秒殺、評論、下單)、降級(返回託底數據或默認數據,如商品詳情頁庫存默認有貨),通過限流,我們可以很好地控制系統的qps,從而達到保護系統的目的。常見的限流算法有令牌桶、漏桶,計數器也可以進行粗暴限流實現。

1.2 冪等

        在編程中.一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。冪等函數,或冪等方法,是指可以使用相同參數重複執行,並能獲得相同結果的函數。這些函數不會影響系統狀態,也不用擔心重複執行會對系統造成改變。例如“setTrue()”函數就是一個冪等函數,無論多次執行,其結果都是一樣的.更復雜的操作冪等保證是利用唯一交易號(流水號)實現。

                   f(f(x)) = f(x)

         x被函數f作用一次和作用無限次的結果是一樣的。冪等性應用在軟件系統中,我把它簡單定義爲:某個函數或者某個接口使用相同參數調用一次或者無限次,其造成的後果是一樣的,在實際應用中一般針對於接口進行冪等性設計。舉個栗子,在系統中,調用方A調用系統B的接口進行用戶的扣費操作時,由於網絡不穩定,A重試了N次該請求,那麼不管B是否接收到多少次請求,都應該保證只會扣除該用戶一次費用。

2. 架構說明

        限流和冪等框架的設計主要是通過註解和攔截器aop的方式來實現,框架本身實現分爲兩個主要部分:限流規則解析和請求對應的限流規則使用,對應的如下圖所示:


下面先介紹框架的限流規則解析部分。

2.1 限流規則解析

在詳細介紹限流規則解析之前,先整體看一下這部分對於類圖結構,如下圖所示:


從上圖可以看出限流規則解析整體分成3塊:註解領域模型,註解解析器和限流規則對應的領域模型,並且這3塊的關係從上圖也能清晰的看出,通過註解解析器從對應的註解中解析出來對應的限流規則,而且註解領域模型和限流規則對應的領域模型實際上一一對象的,下面對這3塊進行詳細介紹【注意限流僅僅限制對應的Public方法】:

(1) 註解領域模型:分別是限流策略,限流組規則,限流規則和限流條件,失效限流策略,失效限流規則,異常自定義處理方法別名註解,如下圖所示:


(2) 註解到規則轉換的解析器:對於註解領域模型中的每一個註解類型定義了一個解析器,用於將對應的註解領域轉換爲對應的規則領域模型。


(3) 規則領域模型:和(1)註解領域模型基本是一樣的。


2.2 限流規則使用

在詳解介紹限流規則的使用前,先來看一下請求處理對應的類圖:


首先攔截器會攔截所有標記有@EnableThrottlingPolicy註解的類的方法,在aroundAdvice方法中根據方法進行限流和冪等攔截,如果訪問到達了接口限流的上限,則異常,需要調用者自己進行異常處理。

2.3註解含義使用說明

(1)限流策略註解:


限流策略註解包含了限流規則註解列表,使用這個限流策略註解的類中的方法要滿足限流策略對應的所有的限流規則列表中定義的限制,注意限流策略註解具有繼承性,也即是在一個類上增加這個註解,則這個類及其子類都會繼承對應的限流策略,當然子類也可以自己進行重寫。

(2)限流組規則註解:


限流組規則可以定義在方法上,增加一個對應限流策略的組規則,這樣這個方法對應的組規則就是類型上定義的限流策略中的規則列表和方法自己定義的規則列表之和(相同名稱的組規則以方法上的爲準),要注意一點的是如果兩個規則對應的名稱一樣,則後面的規則會覆蓋前面的規則。 

(3)限流規則註解:


(4)限流條件註解:


(5)關閉限流策略註解:

@DisableThrottlingPolicy註解是一個標記註解,可以標記在類型和方法中,標記在類型上則這個類對應的方法都不會應用限流規則,應用在方法上則對應的該方法不會應用限流規則。

(6)關閉限流規則註解:


(7)限流異常處理註解


@ThrottlingExceptionRule 限流異常處理規則,其有一個屬性是handleMethodAliasName,這個屬性是對應的異常處理函數對應的別名,這個別名主要是爲了在對應的策略註解,組規則註解以及對應的規則註解中使用,其他使用如下圖所示:


    注意這個對應的異常處理函數的參數類型和順序一定是(ProceedingJoinPoint,ThrottlePolicy,ThrottleException),且對應的方法訪問屬性是Public。如果對應的限流方法上規則沒有增加對應的限流自定義異常處理,則按照原來默認的處理,即是限流條件不通過則拋異常;冪等則直接返回原來的結果。

    使用的時候,只要在註解@EnableThrottlingPolicy或者@ThrottlingGroupRule或者@ThrottlingRule對應的屬性excepHandleMethodAlias設置對應的@ThrottlingExceptionRule中定義的別名即可。

3. 用法說明

3.1框架引入Pom依賴

<dependency>

        <groupId>com.ctim.framework</groupId>

        <artifactId>throttle</artifactId>

        <version>0.0.3-SNAPSHOT</version>

</dependency>

3.2 增加spring對應的組件掃描包路徑

        增加spring對應的組件掃描包路徑 “com.ctim.framework.throttle”,將對應的限流框架引入。例如使用@CompoentScan(“com.ctim.framework.throttle”)

3.3 自定義實現接口ThrottleValueAcquirer

            自定義類實現接口ThrottleValueAcquirer用於獲得對應的限流條件對應的白名單中的值,其中接口ThrottleValueAcquirer對應的方法acquire(Object... objects)中的參數和要限流的方法的參數完成一樣,下面是一個自己實現接口ThrottleValueAcquirer的例子:


3.4 自定義實現接口ThrottlePersistenceService

接口ThrottlePersistenceService定義了一些比較和更新限流策略對應的限流值方法,具體說明如下:




3.5 在類型和方法上增加註解

        在需要進行限流或冪等的接口上增加相應的開啓限流策略的註解,這樣這個類型及其子類型都已經開啓了限流規則,如下圖所示:

(1)在類型上定義的限流策略:

        在類型定義了一個限流策略,這個限流策略包含限流規則列表,這個規則列表中的規則使用的規則entryValue獲取器對應的beanName爲myThrottleValueAcquirer,持久化服務對象使用的組規則的默認值guvva的ratelimiter來實現的,這個規則包含了兩個限流條件:一個是每秒訪問5次,一個是每分鐘訪問200次的限流條件,且這個兩個限流條件對應的白名單中值得獲取器使用的都是myThrottleValueAcquirer來獲取的(這個要和限流條件中的白名單中的值對應的)。


(2)在類型上定義限流策略,在方法上定義對應的組規則


這種定義的方式和(1)實現同樣的功能。

(3)在類型上定義冪等規則策略



冪等規則和限流規則唯一差異就是規則類型不一樣。

(4)類型和方法定義不同規則名稱的規則



類型和方法都定義規則但是對應的規則名稱不一樣,則方法test就對應了兩個規則。

(5)類型和方法上定義相同名稱規則



類型和方法上對應的規則名稱相同,則方法上的規則會覆蓋類型上定義的規則。

(6)類型上同時定義限流和冪等組規則



在類型上定義了一個限流規則和冪等規則。

(7)類型上使用DisableThrottlingPolicy註解

註解@DisableThrottlingPolicy不具有繼承性,父類關閉限流,子類不會關閉限流策略。


在類型上加入關閉限流策略的註解,則這個類中的所有方法都將關閉限流策略。

(8)方法上使用DisableThrottlingPolicy註解

在方法上使用關閉限流策略,則僅僅只對該方法關閉限流策略,類型中的其他方法不受影響。


方法test上加了關閉限流策略的註解,則方法test將不受限流限制,而方法test1仍然受限流策略的限制。

(9)失效限流的特定規則



失效限流規則test1,其他限流規則test2的仍然有效

(10)根據特定規則進行限流

根據特定規則,比如根據訪問ip,userId等進行限流和防刷,則需要自己定義對應的規則註解中的ruleAcquirerBeanName,這個bean需要自己實現,按照什麼規則進行限流和防刷。

(11)自定義對應限流異常處理流程

先定義對應的異常處理方法的別名,如下圖所示:


在限流策略中指定對應的限流異常處理方法別名,如下圖所示:


或者在限流組規則中指定對應的限流異常處理方法別名,如下圖所示:


或者在限流規則中指定對應的限流異常處理方法別名,如下圖所示:


注意自定義異常處理方法指定的覆蓋策略:規則》組規則》策略

4. 代碼地址

https://github.com/lwjaiyjk/Throttle

轉載請說明出處

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