1. 程式人生 > 其它 >4種典型限流實踐保障應用高可用|雲效工程師指北

4種典型限流實踐保障應用高可用|雲效工程師指北

簡介:4種典型限流實踐保障應用高可用,本文總結了一份AHAS限流實踐指南,如果你的系統有被惡意使用者攻擊的風險,或者系統中某個應用出現異常可能會造成雪崩效應,那麼這篇文章會對你有所幫助。

大家好,我叫黃博文,花名延枚,目前負責雲效旗下產品Flow流水線的設計和開發。在微服務架構下,服務越來越多,服務之間的呼叫也會越來越複雜。如何保障服務的高可用性就成為了一個挑戰。之前我參與過的某個產品就曾出過故障,原因是某個API呼叫突然間增加了數十倍,導致服務負載過高,影響了使用者使用。如果當時能夠有一種機制能快速對這個異常的API進行限流或熔斷,就能避免服務陷入不穩定的狀況。雲效自身使用阿里雲 AHAS (Application High Availability Service)來保障應用的高可用,本文總結了一份AHAS限流實踐指南,如果你的系統有被惡意使用者攻擊的風險,或者系統中某個應用出現異常可能會造成雪崩效應,那麼這篇文章會對你有所幫助。

一個完善的應用高可用解決方案,首先需要對應用的介面進行監控,能夠實時統計當前應用介面的QPS情況。其次要能夠針對不同API和場景配置各種限流和熔斷規則,比如如果某個API QPS超過300了就需要對超過的呼叫做限流處理。能夠提供限流的工具很多,流行的有guava RateLimiter、Hystrix等。但這些工具上手成本較高,搭建起整個體系並不簡單。

如何快速建立應用的限流體系?這就要介紹阿里雲提供的應用高可用服務 AHAS (Application High Availability Service)。AHAS 是經阿里巴巴內部多年高可用體系沉澱下來的雲產品,基於阿里開源流控降級元件 Sentinel,以流量與容錯為切入點,從流量控制、不穩定呼叫隔離、熔斷降級、熱點流量防護、系統自適應過載保護、叢集流控、服務防抖動等多個維度來幫助保障服務和閘道器的穩定性,同時提供秒級的流量監控分析功能。AHAS 不僅在阿里內部淘寶、天貓等電商領域有著廣泛的應用,在網際網路金融、線上教育、遊戲、直播行業和其他大型政央企行業也有著大量的實踐。

限流限的是什麼

限流的目的是為了避免系統承受過大的流量導致不可用。那麼這些流量會來自哪裡呢?

按照訪問的方式,可以分為:

  1. HTTP的同步呼叫。比如你在通過瀏覽器訪問一個站點的頁面時候,就會產生這種流量。
  2. 後臺任務呼叫。這個取決於業務形態,比如一個站點向用戶開放了定時執行任務的能力,那麼使用者每多配置一個這種任務,就會對系統造成更多的流量。

按照訪問的意圖,可以分為:

  1. 正常業務增長。比如使用者增加了,做了運營活動等等,都會導致整體的業務量增加。
  2. 惡意使用者的惡意行為。比如某個使用者對站點進行DDOS攻擊,或者對於上面提到的那種提供定時執行任務能力的網站而言,惡意的配置大量的定時任務,從而間接對系統造成巨大的負載,等等。

按照訪問的來源,可以分為:

  1. 終端使用者。這些使用者是最終使用者,其總訪問量會隨著正常業務的增長而增長。
  2. 系統呼叫。比如有其他系統基於你的能力構建自己的產品,那麼就要和這些系統進行約定,訪問的最大頻率是多少,並把這些頻率的值落地在限流策略中。

瞭解了流量的來源之後,我們就知道應該限制什麼了。

  1. 限制整個系統的使用頻率,這個在實際的使用中,通常會換算成單機的使用頻率,保證單機不被壓垮。同時配合告警,出現瓶頸時候,通過緊急擴容來解決問題。
  2. 限制單個使用者(或者單個租戶,取決於你的業務形態)的使用頻率。
  3. 限制上游不同的系統呼叫的使用頻率。
  4. 針對上述的限制,都需要能夠支援HTTP的同步呼叫和後臺任務呼叫。

接下來我們從保證系統整體可用性、防止個別使用者濫用、隔離上游系統異常呼叫以及全方位限流4個方面,具體講解如何使用阿里雲AHAS實現限流。

保證系統整體可用性

配置限流時,我們需要建立一個通用的限流規則保障核心介面的穩定性,避免單點瓶頸引發全域性問題。

一個流控規則包含以下內容:

  • 介面名稱:即對哪個介面進行流控。
  • 來源應用:設定為default,即對所有呼叫方都一視同仁,對整個系統的呼叫進行限流。關於這個配置的用法,會在後面的“針對其他上游系統呼叫的限流”部分展開討論。
  • 單機QPS閾值:單機的QPS容量,超過閾值後會被限流
  • 流控效果:當介面呼叫超過QPS閾值後的處理措施

我們也可以配置觸發限流後的介面返回值。對於Web介面而言,通常被限流的介面會返回429 Too Many Requests錯誤碼,告知呼叫方請求太頻繁。

對一個介面進行限流時,難點是填寫具體的QPS閾值。我們可以在效能測試環境對應用進行壓測,壓出單機下某個介面的QPS極限值,然後將閾值定為極限值的某個比例,比如極限值的90%。比如某個介面單機可承受極限為200QPS,那麼閾值可定為200*90%= 180。

防止個別使用者濫用

這個場景下,需要先梳理出來系統的核心業務入口,通常是service層的一個入口函式,針對每個入口函式預設單個使用者合理的使用頻率,然後就可以利用AHAS的熱點引數流控能力,來並進行限制。

在入口函式上添加註解:

@SentinelResource(value = "biz1")
public Result doBussinessLogic(String uid, int type) {
    // uid引數索引為0,type引數索引為1。
    // some logic here...
}

程式碼中需要做兩件事情

  1. 從請求中提取出需要防護的維度,比如上面程式碼中的uid,即使用者的標識。並保證該標識作為業務入口函式的入參傳入。
  2. 給該函式新增@SentinelResource註解。其中的value="biz1"為這個資源的標識,會用在控制檯配置中進行引用。

然後在控制檯進行配置。假設我們希望,在服務級別每分鐘單使用者最多呼叫20次,服務共有5個例項。則可以進行如下配置。意思是在第0個引數,也就是使用者,這個維度上進行限流,單機最多每60s進行4次呼叫,則叢集維度就是每分鐘最多20次呼叫。

目前AHAS還不支援直接進行叢集維度的配置,實際使用中需要簡單的換算下。

詳細說明,請參考:
配置熱點規則 - 應用高可用服務 AHAS - 阿里雲 。

隔離上游系統異常呼叫

對於一個應用的介面來說,通常會被上游多個系統呼叫。上面雖然介紹瞭如何對單個介面進行整體限流,但實際場景中,我們會需要對不同的上游系統採用不同的限流閾值。比如上游呼叫方A是主鏈路,希望QPS閾值能高一些,上游呼叫方B為旁支鏈路,QPS閾值可以低一些。那麼我們需要在Web容器啟動時注入抽取租戶特徵值的攔截器。根據來源應用標識來對不同來源給予不同的閾值。

@Configuration
public class InterceptorConfiguration extends WebMvcConfigurerAdapter {
    
    @PostConstruct
    public void setOriginParser() {
        WebCallbackManager.setRequestOriginParser(httpServletRequest -> httpServletRequest.getHeader("income"));
    }
}

WebCallbackManager.setRequestOriginParser 接受一個引數為HttpServletRequest的回撥,我們需要通過HttpServletRquest物件中的內容來區分呼叫方A和B。比如應用A和B在呼叫介面時會傳入不同的header income,那麼就可以通過該header來區分來源應用A和B。最後在流控規則中建立起對A和B不同限流閾值。如下圖所示。

 

全方位限流,不限於HTTP

AHAS可以快速的把Web介面納入到流控之中。但如果我們應用的一些程式碼不屬於Web介面,但也想啟用流控,那麼仍然可以使用AHAS提供的熱點規則的能力。以下是個示例。

    @SentinelResource(blockHandler = "blockHandlerExecuteTask")
  public Boolean executeTask(Long taskId) throws Exception {
    return taskService.executeTask(taskId);
    }


    public Boolean blockHandlerExecuteTask(Long taskId, BlockException ex) {
        throw new RuntimeException("execute task exceed");
    }

重啟應用後,在介面詳情頁的自定義埋點tab中,就可以看到AHAS收集的自定義埋點介面資料,介面名稱組成為類名:方法名的格式。

接著可以給這個埋點介面配置限流規則,開啟防護。

以上就是我們使用AHAS服務時配置限流的常用實踐,希望對大家有所幫助。

原文連結

本文為阿里雲原創內容,未經允許不得轉載。