1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Alibaba Sentinel流控詳解

        共 9741字,需瀏覽 20分鐘

         ·

        2021-06-13 18:17

        點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

        優(yōu)質(zhì)文章,第一時間送達(dá)

        概述

         流量控制(flow control),其原理是監(jiān)控應(yīng)用流量的 QPS 或并發(fā)線程數(shù)等指標(biāo),當(dāng)達(dá)到指定的閾值時對流量進(jìn)行控制,以避免被瞬時的流量高峰沖垮,從而保障應(yīng)用的高可用性。

         

        限流類型分為:

        • QPS 每秒請求數(shù)限制

        • 線程數(shù) 資源使用線程數(shù)限制

        流控模式

        • 直接 資源直接限流,這個就是簡單的限流。

        • 關(guān)聯(lián) 關(guān)聯(lián)模式需要填寫關(guān)聯(lián)資源的路徑,意為如果關(guān)聯(lián)資源的流量超額之后,限流自己(自己為資源名填寫的路徑)。

        • 鏈路 如果是鏈路模式需要填寫入口資源,限制入口資源對自己的調(diào)用,這里不太好理解,下面進(jìn)行測試。

        流控效果

        • 快速失敗 直接拋異常了

        • Warm Up 需要填寫預(yù)熱時間,表示,在預(yù)熱時間內(nèi),慢慢的達(dá)到QPS的限制。

        • 排隊(duì)等待 需要填寫超時時間,排隊(duì)很好理解啦。

        1.QPS測試

        設(shè)置/hello的QPS為1。

        @GetMapping(value = "/hello")
        public String hello() {
            return "Hello Sentinel1";
        }

        這個比較好理解,直接快速訪問hello即可。

        正常的時候返回

        Hello Sentinel1

        如果訪問太快,會返回如下,表示流量控制。

        Blocked by Sentinel (flow limiting)

        2.線程數(shù)測試

        線程數(shù)限制,表示執(zhí)行當(dāng)前方法的線程數(shù)控制,因?yàn)樵L問太快,加入sleep,方便測試。

        @GetMapping(value = "/hello")
        public String hello() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello Sentinel1";
        }

        線程數(shù)設(shè)置1

        使用jmeter進(jìn)行測試。jmeter設(shè)置一秒2個請求。在View Results Tree中會有1個成功1個限流。

        至于QPS限制,還是線程限制,需要不同的場景,進(jìn)行選擇。

        3.關(guān)聯(lián)測試

        設(shè)置/hello的關(guān)聯(lián)資源為/hello2,表示如果hello2超過每秒1次的話,限制hello1。這個久很怪異,明明不管我的的事,卻要限制我,但是存在即合理,應(yīng)該也有這樣的場景。

            @GetMapping(value = "/hello")
            public String hello() {
                return "Hello Sentinel1";
            }
            @GetMapping(value = "/hello2")
            public String hello2() {
                return "Hello Sentinel2";
            }

        先通過jmeter對hello進(jìn)行頻繁訪問,正常返回,沒有測試出限流。再對hello2進(jìn)行頻繁訪問,正常返回,沒有限流。

        驗(yàn)證關(guān)聯(lián)控制。jmeter設(shè)置hello2為10秒請求30次,表示前10秒內(nèi)hello返回限流。hello在這15秒請求15次,多5秒就是想測試沒有了hello2的頻繁訪問,是否還限流。

        設(shè)置信息如下。


        hello2的返回信息一切正常。

        hello前10秒限流,后5秒正常返回。

        4.鏈路測試

            @Autowired
            private TestService testService;
            @GetMapping(value = "/hello")
            public String hello() {
                testService.listOrder();
                return "Hello Sentinel1";
            }
            @GetMapping(value = "/hello2")
            public String hello2() {
                testService.listOrder();
                return "Hello Sentinel2";
            }

        @Service
        public class TestService {
            //資源信息
            @SentinelResource("listOrder")
            public void listOrder(){
                System.out.println("listOrder");
            }
        }

        這樣就形成了一個鏈路。一個controller對service調(diào)用的鏈路。在頁面上有如下信息。

        配置listOrder流控,鏈路入口為/hello

        如此,配置即可限制/hellolistOrder的調(diào)用次數(shù)。當(dāng)然在微服務(wù)之間也可以這么去設(shè)置。現(xiàn)在又對這個針對來源的概念模糊了,這兩個不一樣么?針對來源默認(rèn)為default,,表示不區(qū)分來源,處理服務(wù)之間的限制,如果細(xì)化到方法的層面上,針對來源的設(shè)置無法做到,這時就需要進(jìn)行鏈路設(shè)置。

        5.快速失敗

        流控效果中快速失敗是最簡單的限流處理策略,直接拋了個異常。

        自定義失敗

        在被限流的時候拋出 FlowException 異常。FlowException 是 BlockException 的子類,您可以捕捉 BlockException 來自定義被限流之后的處理邏輯。

        官方是這么說的,但是在直接對controller的接口進(jìn)行限制的時候,通過spring全局異常捕獲死活捕獲不到。后來發(fā)現(xiàn)這里發(fā)現(xiàn),這里進(jìn)行controller的流量控制是通過Filter來控制的,所有spring的全局異常根本無法捕獲。

        @ControllerAdvice
        @RestController
        public class CommonException {
            @ExceptionHandler(BlockException.class)
            public String customException(Exception e) {
                return "系統(tǒng)出小差,請稍后再試。";
            }
            @ExceptionHandler(UndeclaredThrowableException.class)
            public String undeclaredThrowableException(Exception e) {
                return "系統(tǒng)出小差,請稍后再試。";
            }
            @ExceptionHandler(Exception.class)
            public String exception(Exception e) {
                return "系統(tǒng)出小差,請稍后再試。";
            }
        }

        如此,可以通過WebCallbackManager.setUrlBlockHandler設(shè)置限流之后的處理類。

        注意:Filter的具體實(shí)現(xiàn)在CommonFilter中,有的版本通過攔截器實(shí)現(xiàn),可以試著搜索AbstractSentinelInterceptor,可能這種小改動不會影響什么,所以貌似官方?jīng)]有說明。

        @Configuration
        public class Config {
        static {
            WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {
                @Override
                public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {
                    // 簡單演示,這里可以自行處理
                    PrintWriter out = response.getWriter();
                    out.print("try again later");
                    out.flush();
                    out.close();
                }
            });
        }
        }

        當(dāng)然,全局異常處理并不能解決所有的問題,更多的時候是希望每個方法都有自己的處理邏輯。

           @SentinelResource(value = "helloResource" ,blockHandler = "getOrderDowngradeRtTypeFallback",fallback = "helloFallback")
            @GetMapping(value = "/hello")
            public String hello(@RequestParam(value = "id") Long id)  {
                if(id==1l){
                    throw  new RuntimeException("1231");
                }
                return "SUCCESS";
            }
            public String helloFallback(Long id,Throwable e) {
                System.out.println(1111);
                return id+"helloFallback";
            }
            public String getOrderDowngradeRtTypeFallback(Long id,BlockException ex) {
                return "服務(wù)降級啦,當(dāng)前服務(wù)器請求次數(shù)過多,請稍后重試!";
            }

        通過SentinelResource注解來自定義異常的處理。

        • blockHandler限流之后的補(bǔ)償處理方法。這里是限流的請求才會執(zhí)行這個方法。另外,還有blockHandlerClass效果一樣。

        • fallback 如果方法中有異常則執(zhí)行fallback指定的方法。另外,還有fallbackClass指定處理類,效果是一樣的。

        另外需要注意的是,如果添加SentinelResource注解之后,在控制臺會有如下信息。兩個都可以對這個方法進(jìn)行限制,但是/hello是通過Filter實(shí)現(xiàn)的(后面改成了攔截器)全局異常可能是攔截不到的哦,具體可以看源碼CommonFilter或者AbstractSentinelInterceptor,helloResource是通過AOP來實(shí)現(xiàn)的,所以全局異常是可以對此進(jìn)行處理的,源碼SentinelResourceAspect

        在使用之前版本的時候fallback 死活不好用,不知道是不是版本BUG。換成了這個版本就好用了, 也是在這個版本使用的時候,發(fā)現(xiàn)conroller限流從Filter變成了攔截器。

        <dependencyManagement>
                <dependencies>
                    <dependency>
                        <groupId>org.springframework.cloud</groupId>
                        <artifactId>spring-cloud-dependencies</artifactId>
                        <version>Hoxton.RELEASE</version>
                        <type>pom</type>
                        <scope>import</scope>
                    </dependency>
                    <dependency>
                        <groupId>com.alibaba.cloud</groupId>
                        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                        <version>2.2.1.RELEASE</version>
                        <type>pom</type>
                        <scope>import</scope>
                    </dependency>
                </dependencies>
            </dependencyManagement>

        6.Warm Up

        這個是一個預(yù)熱的概念,比如服務(wù)剛剛啟動,所有的緩存還在加載中,不能有太多的請求進(jìn)來,所以需要進(jìn)行一個服務(wù)的預(yù)熱,剛啟動QPS限制小于設(shè)定數(shù)值,待服務(wù)啟動一段時間后,慢慢的達(dá)到所設(shè)置的QPS。

         規(guī)則設(shè)置之后開始預(yù)熱。

        如此設(shè)置,即可發(fā)現(xiàn),開始的5秒中,QPS特別小,然后慢慢增加,到5秒的時候達(dá)到每秒10QPS。

        7.排隊(duì)等待

        設(shè)置超時時間后,如果QPS限制之后,會等待,超過設(shè)定時間后,拋出BlockException異常。



        本文鏈接:

        https://blog.csdn.net/qq_30285985/article/details/107692608








        瀏覽 47
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            女人被狂躁到高潮视频无遮挡 | 丁香五月亚洲激情 | 韩国一级黄色片 | 91露脸熟女四川熟女在线观看 | 久久久久久国产精品免费 | 欧美A V在线 | 丰满秘书调教h | 国内爆初菊对白视频 | 亚洲五月网 | 小黄片观看 |