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>

        阿里限流神器Sentinel奪命連環(huán) 17 問?

        共 22837字,需瀏覽 46分鐘

         ·

        2021-11-24 02:01

        1、前言

        這是《Spring Cloud 進階》專欄的第五篇文章,這篇文章介紹一下阿里開源的流量防衛(wèi)兵Sentinel,一款非常優(yōu)秀的開源項目,經(jīng)過近10年的雙十一的考驗,非常成熟的一款產(chǎn)品。往期文章如下:

        文章目錄如下:

        2、什么是sentinel?

        sentinel顧名思義:衛(wèi)兵;在Redis中叫做哨兵,用于監(jiān)控主從切換,但是在微服務(wù)中叫做流量防衛(wèi)兵。

        Sentinel 以流量為切入點,從流量控制、熔斷降級系統(tǒng)負載保護等多個維度保護服務(wù)的穩(wěn)定性。

        Sentinel 具有以下特征:

        • 豐富的應(yīng)用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發(fā)流量控制在系統(tǒng)容量可以承受的范圍)、消息削峰填谷、集群流量控制、實時熔斷下游不可用應(yīng)用等。
        • 完備的實時監(jiān)控:Sentinel 同時提供實時的監(jiān)控功能。您可以在控制臺中看到接入應(yīng)用的單臺機器秒級數(shù)據(jù),甚至 500 臺以下規(guī)模的集群的匯總運行情況。
        • 廣泛的開源生態(tài):Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相應(yīng)的依賴并進行簡單的配置即可快速地接入 Sentinel。同時 Sentinel 提供 Java/Go/C++ 等多語言的原生實現(xiàn)。
        • 完善的 SPI 擴展機制:Sentinel 提供簡單易用、完善的 SPI 擴展接口。您可以通過實現(xiàn)擴展接口來快速地定制邏輯。例如定制規(guī)則管理、適配動態(tài)數(shù)據(jù)源等。

        Sentinel 的主要特性如下圖

        Sentinel 分為兩個部分:

        • 核心庫(Java 客戶端)不依賴任何框架/庫,能夠運行于所有 Java 運行時環(huán)境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持。
        • 控制臺(Dashboard)基于 Spring Boot 開發(fā),打包后可以直接運行,不需要額外的 Tomcat 等應(yīng)用容器。

        總之一句話:sentinel真牛逼,完爆Hystrix.........

        3、sentinel和Hystrix有何區(qū)別?

        不多說了,總之一句話:Hystrix趕緊放棄,用sentinel......

        具體區(qū)別如下圖:

        4、sentinel版本如何選擇?

        由于陳某寫的是Spring Cloud 進階一個系列,使用的聚合項目,因此版本還是保持和之前文章一樣,不清楚的可以看這篇:五十五張圖告訴你微服務(wù)的靈魂擺渡者Nacos究竟有多強?

        這里選擇的spring-cloud-alibaba-dependencies的版本是2.2.1.RELEASE,因此sentinel版本選擇1.7.1,大家可以根據(jù)自己的版本選擇對應(yīng)sentinel的版本,版本對應(yīng)關(guān)系如下圖:

        注意:一定要按照官方推薦的版本適配,否則出現(xiàn)意想不到的BUG追悔莫及.........

        5、Sentinel 控制臺如何安裝?

        sentinel和nacos一樣,都有一個控制臺,但是這里不用自己手動搭建一個微服務(wù),官方已經(jīng)搭建好了,只需要下載對應(yīng)得jar包運行即可。下載地址:https://github.com/alibaba/Sentinel/tags

        選擇對應(yīng)得版本下載即可,我這里選擇1.7.1版本,下載的jar包如下圖:

        當(dāng)然你可以通過源碼構(gòu)建:mvn clean package

        注意:JDK版本必須>=1.8

        此時我們只需要運行這個jar包即可,命令如下:

        java?-Dserver.port=8080?-Dcsp.sentinel.dashboard.server=localhost:8080?-Dproject.name=sentinel-dashboard?-jar?sentinel-dashboard-1.7.1.jar

        上述參數(shù)含義如下:

        • -Dserver.port:指定啟動的端口,默認8080

        • -Dproject.name:指定本服務(wù)的名稱

        • -Dcsp.sentinel.dashboard.server:指定sentinel控制臺的地址,用于將自己注冊進入實現(xiàn)監(jiān)控自己

        啟動成功之后,瀏覽器訪問:http://localhost:8080,登錄頁面如下圖:

        默認的用戶名和密碼:sentinel/sentinel

        登錄成功之后頁面如下:

        可以看到目前只有一個服務(wù)sentinel-dashboard被監(jiān)控了,這個服務(wù)就是自己。

        注意:上述參數(shù)都是可選的,沒必要可以不填。

        那么問題來了:默認的用戶名和密碼在生產(chǎn)環(huán)境上肯定不能用,如何修改呢?

        從 Sentinel 1.6.0 起sentinel已經(jīng)支持自定義用戶名和密碼了,只需要在執(zhí)行jar命令時指定即可,命令如下:

        java?-Dsentinel.dashboard.auth.username=admin?-Dsentinel.dashboard.auth.password=123?-jar?sentinel-dashboard-1.7.1.jar

        用戶可以通過如下參數(shù)進行配置:

        • -Dsentinel.dashboard.auth.username=sentinel 用于指定控制臺的登錄用戶名為 sentinel;
        • -Dsentinel.dashboard.auth.password=123456 用于指定控制臺的登錄密碼為 123456;如果省略這兩個參數(shù),默認用戶和密碼均為 sentinel;
        • -Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服務(wù)端 session 的過期時間,如 7200 表示 7200 秒;60m 表示 60 分鐘,默認為 30 分鐘;

        注意:部署多臺控制臺時,session 默認不會在各實例之間共享,這一塊需要自行改造。

        除了用戶名密碼相關(guān)的配置,sentinel控制臺還提供了其他的可配置選項,如下圖:

        6、微服務(wù)如何接入sentinel控制臺?

        微服務(wù)為什么要集成sentinel控制臺,sentinel不是提供了相關(guān)的API嗎?

        其實Spring Boot 官方一直提倡約定>配置>編碼的規(guī)則,能夠不硬編碼何樂而不為呢?

        因此本文后續(xù)內(nèi)容主要還是結(jié)合sentinel控制臺進行講解,關(guān)于API的使用大家可以按照官方文檔學(xué)習(xí),講解的非常清楚。

        好了,言歸正傳,微服務(wù)如何接入sentinel控制臺呢?

        1、新建微服務(wù)模塊注冊進入Nacos

        這里的注冊中心依然使用的是nacos,有不會用的請看專欄第一篇Nacos文章:五十五張圖告訴你微服務(wù)的靈魂擺渡者Nacos究竟有多強?

        新建一個微服務(wù)模塊:sentinel-service9008,相關(guān)代碼不貼出了。

        相關(guān)配置如下:

        server:
        ??port:?9008
        spring:
        ??application:
        ????##?指定服務(wù)名稱,在nacos中的名字
        ????name:?sentinel-service
        ??cloud:
        ????nacos:
        ??????discovery:
        ????????#?nacos的服務(wù)地址,nacos-server中IP地址:端口號
        ????????server-addr:?127.0.0.1:8848
        management:
        ??endpoints:
        ????web:
        ??????exposure:
        ????????##?yml文件中存在特殊字符,必須用單引號包含,否則啟動報錯
        ????????include:?'*'

        源碼全部會上傳,獲取方式看文末!

        2、添加依賴

        除了Nacos的依賴,還需要添加一個sentinel的依賴:


        <dependency>
        ?<groupId>com.alibaba.cloudgroupId>
        ?<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
        dependency>

        以上只貼出了sentinel相關(guān)依賴,nacos依賴不再貼了,見源碼!

        3、添加配置集成控制臺

        只需要添加如下配置即可集成sentinel控制臺:

        spring:
        ??cloud:
        ????sentinel:
        ??????transport:
        ???????##?指定控制臺的地址,默認端口8080
        ????????dashboard:?localhost:8080

        4、新建一個測試接口

        下面新建一個測試接口,用于測試相關(guān)規(guī)則,如下:

        @RestController
        @RequestMapping("/sentinel")
        public?class?FlowLimitController?{

        ????@GetMapping("/test")
        ????public?String?test(){
        ????????return?"接收到一條消息--------";
        ????}
        }

        5、啟動微服務(wù)

        啟動9008這個微服務(wù),然后瀏覽器輸入:http://localhost:9008/sentinel/test,此時查看sentinel控制臺,將會看見sentinel-service這個服務(wù)已經(jīng)被監(jiān)控了,如下圖:

        注意:sentinel是懶加載機制,只有訪問過一次的資源才會被監(jiān)控。

        不過可以通過配置關(guān)閉懶加載,在項目啟動時就連接sentinel控制臺,配置如下:

        spring:
        ????sentinel:
        ??????#?取消控制臺懶加載,項目啟動即連接Sentinel
        ??????eager:?true

        7、流量控制如何配置?

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

        QPS:每秒請求數(shù),即在不斷向服務(wù)器發(fā)送請求的情況下,服務(wù)器每秒能夠處理的請求數(shù)量。

        并發(fā)線程數(shù):指的是施壓機施加的同時請求的線程數(shù)量。

        同一個資源可以創(chuàng)建多條限流規(guī)則,一條限流規(guī)則由以下元素組成:

        • resource:資源名,即限流規(guī)則的作用對象。
        • count:?限流閾值
        • grade:限流閾值類型(1:QPS ?0:并發(fā)線程數(shù)),默認值QPS
        • limitApp:流控針對的調(diào)用來源,若為 default 則不區(qū)分調(diào)用來源,默認值default
        • strategy:判斷的根據(jù)是資源自身**(0),還是根據(jù)其它關(guān)聯(lián)資源 (1),還是根據(jù)鏈路入口(2)**,默認值根據(jù)資源本身。
        • controlBehavior:?流控效果(直接拒絕(0) / 排隊等待(2) / 預(yù)熱冷啟動(1)),默認值直接拒絕。

        以上元素限流元素對應(yīng)的類是com.alibaba.csp.sentinel.slots.block.flow.FlowRule,各元素如下圖:

        注意:各個元素的取值以及默認值一定要記住,后續(xù)配置將會用到。

        以上幾個元素在sentinel控制臺對應(yīng)規(guī)則如下圖:

        1、三種流控效果

        流控效果總共分為三種,對應(yīng)元素controlBehavior,分別如下:

        快速失敗

        默認的流量控制方式,當(dāng)QPS超過任意規(guī)則的閾值后,新的請求就會被立即拒絕,拒絕方式為拋出FlowException。

        warm up

        預(yù)熱/冷啟動方式。當(dāng)系統(tǒng)長期處于低水位的情況下,當(dāng)流量突然增加時,直接把系統(tǒng)拉升到高水位可能瞬間把系統(tǒng)壓垮。通過"冷啟動",讓通過的流量緩慢增加,在一定時間內(nèi)逐漸增加到閾值上限,給冷系統(tǒng)一個預(yù)熱的時間,避免冷系統(tǒng)被壓垮。

        注意:這一效果只針對QPS流控,并發(fā)線程數(shù)流控不支持。

        預(yù)熱底層是根據(jù)令牌桶算法實現(xiàn)的,源碼對應(yīng)得類在com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController。

        算法中有一個冷卻因子coldFactor,默認值是3,即請求 QPS 從 threshold(閾值) / 3 開始,經(jīng)預(yù)熱時長逐漸升至設(shè)定的 QPS 閾值。

        比如設(shè)定QPS閾值為3,流控效果為warm up,預(yù)熱時長為5秒,如下圖:

        這樣配置之后有什么效果呢:QPS起初會從(3/3/=1)每秒通過一次請求開始預(yù)熱直到5秒之后達到每秒通過3次請求。動態(tài)效果圖如下:

        從上述動畫可以清楚的看見:前幾秒是頻繁流控的,直到5秒,QPS閾值達到了3。

        具體算法原理請看:https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8

        排隊等待

        勻速排隊方式會嚴格控制請求通過的間隔時間,也即是讓請求以均勻的速度通過,對應(yīng)的是漏桶算法。源碼對應(yīng)得類:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController

        注意:這一效果只針對QPS流控,并發(fā)線程數(shù)流控不支持。

        簡單舉個栗子:你去大學(xué)食堂吃飯,只有一個阿姨在打飯,那么所有人都要排隊打飯,每次只有一個人打到飯,其他人都在排隊等待。

        不同的是sentinel有個超時等待時間,一旦超過這個預(yù)定設(shè)置的時間將會被限流。

        該方式作用如下圖:

        這種方式適合用于請求以突刺狀來到,這個時候我們不希望一下子把所有的請求都通過,這樣可能會把系統(tǒng)壓垮;同時我們也期待系統(tǒng)以穩(wěn)定的速度,逐步處理這些請求,以起到“削峰填谷”的效果,而不是拒絕所有請求。

        比如設(shè)置QPS閾值為1,超時等待時間為10000毫秒,如下圖:

        此時的效果如下:

        從上圖可以看到:連續(xù)點擊刷新請求,雖然設(shè)置了QPS閾值為1,但是并沒有被限流,而是在等待,因為設(shè)置了超時等待時間為10秒。

        具體算法原理請看:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6-%E5%8C%80%E9%80%9F%E6%8E%92%E9%98%9F%E6%A8%A1%E5%BC%8F

        2、三種流控模式

        流控模式總共分為三種,對應(yīng)元素strategy,分別如下:

        • 直接拒絕:接口達到限流條件時,直接限流
        • 關(guān)聯(lián):當(dāng)關(guān)聯(lián)的資源達到閾值時,就限流自己
        • 鏈路:只記錄指定鏈路上的流量(指定資源從入口資源進來的流量,如果達到閾值,就可以限流)

        下面來詳細介紹下以上三種流控模式。

        直接拒絕

        顧名思義:默認的流量控制方式,當(dāng)QPS超過任意規(guī)則的閾值后,新的請求就會被立即拒絕,拒絕方式為拋出FlowException。上面的幾個例子都是配置了直接拒絕這個模式,這里不再詳細介紹。

        關(guān)聯(lián)

        典型的使用場景:一個是支付接口,一個是下單接口,此時一旦支付接口達到了閾值,那么訂單接口就應(yīng)該被限流,不然這邊還在下單,消費者等待或者直接被拒絕支付將會極大的影響用戶體驗。

        簡而言之:A關(guān)聯(lián)B,一旦B達到閾值,則A被限流

        演示一下效果,創(chuàng)建以下兩個接口:

        @RestController
        @RequestMapping("/sentinel")
        public?class?FlowLimitController?{

        ????/**
        ?????*?下單接口
        ?????*?@return
        ?????*/

        ????@GetMapping("/order")
        ????public?String?order()??{
        ????????return?"下單成功..........";
        ????}

        ????/**
        ?????*?支付接口
        ?????*?@return
        ?????*/

        ????@GetMapping("/pay")
        ????public?String?pay()??{
        ????????return?"支付成功..........";
        ????}
        }

        此時的流控規(guī)則配置如下圖:

        注意:關(guān)聯(lián)之后,這里設(shè)置的限流規(guī)則是對被關(guān)聯(lián)資源,也就是/sentinel/pay這個資源,但是真正被限流則是/sentinel/order。

        如何演示效果呢?很簡單,只需要不斷的請求/sentinel/pay達到閾值,然后在請求/sentinel/order。

        利用POSTMAN不斷向/sentinel/pay發(fā)出請求,然后瀏覽器請求/sentinel/order,結(jié)果如下圖:

        可以看到訂單接口被限流了.............

        3、兩種統(tǒng)計類型

        流控分為兩種統(tǒng)計類型,分別是QPS,并發(fā)線程數(shù),很多人不太明白這兩種統(tǒng)計類型有什么區(qū)別?

        舉個栗子:陳某帶了一個億去銀行存錢,但是銀行大門保安要查健康碼,每秒最多只能同時進入4個人,并且銀行中只有兩個工作人員工作,如下圖:

        此時的QPS含義:從保安到銀行這一段,即是保安放行進入銀行的人數(shù)。

        此時并發(fā)線程數(shù)的含義:銀行只有兩個工作人員在工作,那么最多只能同時處理兩個任務(wù),這里并發(fā)線程數(shù)的閾值就是2。

        8、降級規(guī)則如何配置?

        熔斷降級在日常生活中也是比較常見的,場景如下:

        • 股票市場的熔斷,當(dāng)價格觸發(fā)到了熔點之后,會暫停交易一段時間,或者交易可以繼續(xù)進行,但是報價會限制在一定的范圍。
        • 電壓過高導(dǎo)致保險絲觸發(fā)熔斷保護

        在大型的分布式系統(tǒng)中,一個請求的依賴如下圖:

        如果這個時候,某個服務(wù)出現(xiàn)一些異常,比如:

        • 服務(wù)提供者不可用(硬件故障、程序bug、網(wǎng)絡(luò)故障、用戶請求量較大)
        • 重試導(dǎo)致的流量過大
        • 服務(wù)調(diào)用者使用同步調(diào)用,產(chǎn)生大量的等待線程占用系統(tǒng)資源,一旦線程資源被耗盡,調(diào)用者提供的服務(wù)也會變成不可用狀態(tài)

        那么將會導(dǎo)致整個服務(wù)不可用,用古話來講就是:千里之堤毀于蟻穴

        所謂編程源于生活,架構(gòu)師們根據(jù)生活的經(jīng)驗設(shè)計出了服務(wù)的熔斷降級策略,很好的解決了這類問題。

        熔斷降級規(guī)則對應(yīng)sentinel控制臺的降級規(guī)則這一欄,如下圖:

        熔斷降級涉及到的幾個屬性如下表:

        源碼中對應(yīng)得類為:com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule

        三種熔斷策略

        Sentinel 提供以下幾種熔斷策略:

        1. 平均響應(yīng)時間 (DEGRADE_GRADE_RT):當(dāng) 1s 內(nèi)持續(xù)進入 5 個請求,對應(yīng)時刻的平均響應(yīng)時間(秒級)均超過閾值(count,以 ms 為單位),那么在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內(nèi),對這個方法的調(diào)用都會自動地熔斷(拋出 DegradeException)。注意 Sentinel 默認統(tǒng)計的 RT 上限是 4900 ms,超出此閾值的都會算作 4900 ms,若需要變更此上限可以通過啟動配置項 -Dcsp.sentinel.statistic.max.rt=xxx 來配置。
        2. 異常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):當(dāng)資源的每秒請求量 >= 5,并且每秒異??倲?shù)占通過量的比值超過閾值(DegradeRule 中的 count)之后,資源進入降級狀態(tài),即在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內(nèi),對這個方法的調(diào)用都會自動地返回。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%。
        3. 異常數(shù) (DEGRADE_GRADE_EXCEPTION_COUNT):當(dāng)資源近 1 分鐘的異常數(shù)目超過閾值之后會進行熔斷。注意由于統(tǒng)計時間窗口是分鐘級別的,若 timeWindow 小于 60s,則結(jié)束熔斷狀態(tài)后仍可能再進入熔斷狀態(tài)。

        下面演示一個平均響應(yīng)時間熔斷,創(chuàng)建一個接口,如下:

        @RestController
        @RequestMapping("/sentinel/provider")
        @Slf4j
        public?class?FlowLimitController?{

        ????@GetMapping("/test")
        ????public?String?test()?throws?InterruptedException?{
        ????????//休眠3秒鐘
        ????????Thread.sleep(3000);
        ????????log.info("收到一條消息----test");
        ????????return?"接收到一條消息--------";
        ????}
        }

        在控臺為這個接口設(shè)置平均響應(yīng)時間為200毫秒,時間窗口為1秒,大致意思:平均的響應(yīng)時間大于200毫秒之后,在接下來的1秒時間內(nèi)將會直接熔斷,如下圖:

        使用Jmeter開啟10個線程循環(huán)跑,然后在瀏覽器中訪問這個接口,返回結(jié)果如下圖:

        為什么呢?由于的接口中休眠了3秒,平均響應(yīng)時間肯定大于200毫秒,因此直接被熔斷了。

        注意:這里熔斷后直接返回默認的信息,后面會介紹如何定制熔斷返回信息。

        9、熱點參數(shù)如何限流?

        顧名思義:熱點就是經(jīng)常訪問的數(shù)據(jù),很多時候肯定是希望統(tǒng)計某個訪問頻次Top K數(shù)據(jù)并對其進行限流。

        比如秒殺系統(tǒng)中的商品ID,對于熱點商品那一瞬間的并發(fā)量是非常可怕的,因此必須要對其進行限流。

        Sentinel 利用 LRU 策略統(tǒng)計最近最常訪問的熱點參數(shù),結(jié)合令牌桶算法來進行參數(shù)級別的流控。

        注意:熱點參數(shù)限流只針對QPS。

        官方文檔:https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81

        概念理解了,來看下sentinel控制臺如何設(shè)置熱點參數(shù)限流,如下圖:

        規(guī)則對應(yīng)得源碼在com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule這個類中,各種屬性含義如下圖:

        規(guī)則都懂了,下面我們通過實戰(zhàn)來演示一下熱點參數(shù)到底是如何限流的。

        注意:熱點參數(shù)限流只作用于八大基本類型。

        1、創(chuàng)建一個資源

        現(xiàn)在先創(chuàng)建一個service,用@SentinelResource這個注解定義一個資源,這個注解后續(xù)將會詳細介紹,先忽略,代碼如下:

        @Service
        @Slf4j
        public?class?FlowServiceImpl?implements?FlowService?{

        ????/**
        ?????*?@SentinelResource的value屬性指定了資源名,一定要唯一
        ?????*?blockHandler屬性指定了兜底方法
        ?????*/

        ????@Override
        ????@SentinelResource(value?=?"OrderQuery",blockHandler?=?"handlerQuery")
        ????public?String?query(String?p1,?String?p2)?{
        ????????log.info("查詢商品,p1:{},p2:{}",p1,p2);
        ????????return?"查詢商品:success";
        ????}

        ????/**
        ?????*?對應(yīng)得兜底方法,一旦被限流將會調(diào)用這個方法來處理
        ?????*/

        ????public?String?handlerQuery(@RequestParam(value?=?"p1",required?=?false)?String?p1,
        ???????????????????????????????@RequestParam(value?=?"p2",required?=?false)String?p2,
        ???????????????????????????????BlockException?exception)
        {
        ????????log.info("查詢商品,p1:{},p2:{}",p1,p2);
        ????????return?"查詢商品:熔斷了......";
        ????}
        }

        上述代碼什么意思呢?如下:

        • 如果query這個接口沒有被限流則返回:查詢商品:success
        • 如果query這個接口被限流了,則進入了兜底方法handlerQuery方法,返回:查詢商品:熔斷了......

        2、創(chuàng)建controller接口

        下面創(chuàng)建一個controller進行測試,代碼如下:

        @RestController
        @RequestMapping("/sentinel/provider")
        @Slf4j
        public?class?FlowLimitController?{
        ????@Autowired
        ????private?FlowService?flowService;

        ????@GetMapping("/order/query")
        ????public?String?query(@RequestParam(value?=?"p1",required?=?false)?String?p1,?@RequestParam(value?=?"p2",required?=?false)String?p2){
        ????????return?flowService.query(p1,p2);
        ????}

        }

        可以看到接口中有兩個參數(shù),分別是p1、p2

        3、添加熱點參數(shù)限流規(guī)則

        在sentinel控制臺點擊熱點規(guī)則->新增熱點限流規(guī)則,添加如下圖規(guī)則:

        上述配置的具體含義:當(dāng)OrderQuery這個資源中的第0個參數(shù)QPS超過1秒1次將會被限流。這里參數(shù)索引是從0開始,第0個就是對應(yīng)接口中的p1這個參數(shù)。

        第一個測試:瀏覽器直接訪問:http://localhost:9009/sentinel/provider/order/query?p1=22&p2=1222,連續(xù)點擊將會看到這個接口被熔斷降級了,如下圖:

        這也正是驗證了上述的熱點參數(shù)限流配置。

        第二個測試:瀏覽器輸入:http://localhost:9009/sentinel/provider/order/query?p2=1222,連續(xù)點擊將會看到這個接口并沒有被熔斷降級,如下圖:

        注意:對于熱點參數(shù)限流,只有包含指定索引的參數(shù)請求才會被限流,否則不影響。

        此時產(chǎn)品說:ID為100的這個產(chǎn)品點擊量太少了,你們趕緊調(diào)整下這個商品的限流規(guī)則。這個時候該怎么辦呢?

        別著急,sentinel顯然考慮到了這一點,提供了參數(shù)例外項這項配置,針對產(chǎn)品需求配置如下:

        從上圖配置中,我們將參數(shù)值p1這個參數(shù)值等于100的時候,限流閾值設(shè)置成了100,也就是說p1=100這個請求QPS放寬到1秒請求100次以上才會被限流。

        驗證:瀏覽器輸入地址:http://localhost:9009/sentinel/provider/order/query?p1=100,無論點擊多么快,都沒有被熔斷降級,顯然是配置生效了,如下圖:

        以上源碼在sentinel-openfeign-provider9009這個模塊中,文末有源碼獲取方式。

        10、系統(tǒng)自適應(yīng)如何限流?

        前面熱點參數(shù)、普通流量限流都是針對的某個接口,這里系統(tǒng)自適應(yīng)限流針對是整個系統(tǒng)的入口流量,從單臺機器的 load、CPU 使用率平均 RT、入口 QPS并發(fā)線程數(shù)等幾個維度監(jiān)控應(yīng)用指標(biāo),讓系統(tǒng)盡可能跑在最大吞吐量的同時保證系統(tǒng)整體的穩(wěn)定性。

        sentinel控制臺對應(yīng)如下圖:

        閾值類型有五種,分別如下:

        • Load 自適應(yīng)(僅對 Linux/Unix-like 機器生效):系統(tǒng)的 load1 作為啟發(fā)指標(biāo),進行自適應(yīng)系統(tǒng)保護。當(dāng)系統(tǒng) load1 超過設(shè)定的啟發(fā)值,且系統(tǒng)當(dāng)前的并發(fā)線程數(shù)超過估算的系統(tǒng)容量時才會觸發(fā)系統(tǒng)保護(BBR 階段)。系統(tǒng)容量由系統(tǒng)的 maxQps * minRt 估算得出。設(shè)定參考值一般是 CPU cores * 2.5。
        • CPU usage(1.5.0+ 版本):當(dāng)系統(tǒng) CPU 使用率超過閾值即觸發(fā)系統(tǒng)保護(取值范圍 0.0-1.0),比較靈敏。
        • 平均 RT:當(dāng)單臺機器上所有入口流量的平均 RT 達到閾值即觸發(fā)系統(tǒng)保護,單位是毫秒。
        • 并發(fā)線程數(shù):當(dāng)單臺機器上所有入口流量的并發(fā)線程數(shù)達到閾值即觸發(fā)系統(tǒng)保護。
        • 入口 QPS:當(dāng)單臺機器上所有入口流量的 QPS 達到閾值即觸發(fā)系統(tǒng)保護。

        官方文檔:https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81

        系統(tǒng)規(guī)則的配置比較簡單,這里以入口QPS為例進行演示,為了演示真實情況,清掉所有的限流規(guī)則,添加系統(tǒng)規(guī)則,如下圖:

        這個QPS系統(tǒng)規(guī)則一配置,該微服務(wù)中的所有接口都將會被這個規(guī)則限制,比如訪問:http://localhost:9009/sentinel/provider/pay,連續(xù)點擊,如下圖:

        可以看到已經(jīng)被限流了,不僅是這個接口,所有接口都會生效。

        注意:系統(tǒng)規(guī)則中的入口QPS這個規(guī)則不建議配置,一旦配置上了可能導(dǎo)致整個服務(wù)不可用。

        11、如何自定義限流返回的異常信息?

        在前面的例子中,無論是熔斷降級還是被限流返回的異常信息都是Blocked by Sentinel (flow limiting),這個是Sentinel默認的異常信息。

        很顯然默認的異常信息并不能滿足我們的業(yè)務(wù)需求,因此我們需要根據(jù)前后端規(guī)則制定自己的異常返回信息。

        這里將會用到一個注解@SentinelResource,這個在上文也是提到過,這個注解中有兩個關(guān)于限流兜底方法的屬性,如下:

        • blockHandler:對應(yīng)處理 BlockException 的函數(shù)名稱。blockHandler 函數(shù)訪問范圍需要是 public,返回類型需要與原方法相匹配,參數(shù)類型需要和原方法相匹配并且最后加一個額外的參數(shù),類型為 BlockException。blockHandler 函數(shù)默認需要和原方法在同一個類中。
        • blockHandlerClass:指定 blockHandlerClass 為對應(yīng)的類的 Class 對象,注意對應(yīng)的函數(shù)必需為 static 函數(shù),否則無法解析。

        官方文檔:https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81

        使用@SentinelResource注解自定義一個限流異常返回信息,先自定義一個資源,指定兜底方法為handler,代碼如下:

        第二步:寫個對應(yīng)得兜底方法,必須在同一個類中,代碼如下:

        第三步:對資源QueryOrder新增一個限流規(guī)則,如下圖:

        第四步:寫個controller,代碼就不曬了,自己寫吧,哈哈。。。。

        第五步:調(diào)用接口,瘋狂點擊,將會出現(xiàn)兜底方法中定義的返回信息,如下圖:

        到這兒基本算是成功了,但是有個問題:兜底方法必須要和業(yè)務(wù)方法放在同一個類中,這樣代碼耦合度不是很高嗎?

        @SentinelResource提供一個屬性blockHandlerClass,完美的解決了這一個問題,能夠?qū)⒍档追椒▎为毞旁谝粋€類中,下面來介紹一下。

        第一步:新建一個單獨的類CommonHandler來放置兜底方法,代碼如下:

        第二步:在@SentinelResource注解中指定blockHandlerClass為上面的類,blockHandler指定兜底方法名,代碼如下:

        好了,至此就完成了,自己照著試試吧.......

        上述源碼在sentinel-openfeign-provider9009這個模塊中,源碼獲取方式見文末。

        12、如何對異常進行降級處理?

        程序員每天都在制造BUG,沒有完美的代碼,也沒有完美的程序員,針對代碼的運行時異常我們無法避免,但是我們可以當(dāng)出現(xiàn)異常的時候進行捕獲并做出相應(yīng)的處理,我們稱之為降級處理。

        異常的降級還是要用到@SentinelResource注解,其中相關(guān)的幾個屬性如下:

        • fallback:fallback 函數(shù)名稱,可選項,用于在拋出異常的時候提供 fallback 處理邏輯。fallback 函數(shù)可以針對所有類型的異常(除了 exceptionsToIgnore 里面排除掉的異常類型)進行處理。fallback 函數(shù)簽名和位置要求:
          • 返回值類型必須與原函數(shù)返回值類型一致;
          • 方法參數(shù)列表需要和原函數(shù)一致,或者可以額外多一個 Throwable 類型的參數(shù)用于接收對應(yīng)的異常。
          • fallback 函數(shù)默認需要和原方法在同一個類中。若希望使用其他類的函數(shù),則可以指定 fallbackClass 為對應(yīng)的類的 Class 對象
        • fallbackClass:指定對應(yīng)的類的 Class 對象,注意對應(yīng)的函數(shù)必需為 static 函數(shù),否則無法解析。
        • defaultFallback(since 1.6.0):默認的 fallback 函數(shù)名稱,可選項,通常用于通用的 fallback 邏輯(即可以用于很多服務(wù)或方法)。默認 fallback 函數(shù)可以針對所有類型的異常(除了 exceptionsToIgnore 里面排除掉的異常類型)進行處理。若同時配置了 fallback 和 defaultFallback,則只有 fallback 會生效。defaultFallback 函數(shù)簽名要求:
          • 返回值類型必須與原函數(shù)返回值類型一致;
          • 方法參數(shù)列表需要為空,或者可以額外多一個 Throwable 類型的參數(shù)用于接收對應(yīng)的異常。
          • defaultFallback 函數(shù)默認需要和原方法在同一個類中。若希望使用其他類的函數(shù),則可以指定 fallbackClass 為對應(yīng)的類的 Class 對象,注意對應(yīng)的函數(shù)必需為 static 函數(shù),否則無法解析。
        • exceptionsToIgnore(since 1.6.0):用于指定哪些異常被排除掉,不會計入異常統(tǒng)計中,也不會進入 fallback 邏輯中,而是會原樣拋出。

        1.8.0 版本開始,defaultFallback 支持在類級別進行配置。

        注:1.6.0 之前的版本 fallback 函數(shù)只針對降級異常(DegradeException)進行處理,不能針對業(yè)務(wù)異常進行處理。

        官方文檔:https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81

        下面定義一個創(chuàng)建訂單的接口,手動制造一個1/0異常,代碼如下:

        上述接口并沒有進行異常降級處理,因此調(diào)用該接口直接返回了異常信息,非常不友好,如下圖:

        我們可以使用fallback指定異常降級的兜底方法,此時業(yè)務(wù)方法改造如下:

        使用fallbackClass屬性指定單獨一個類處理異常降級,降低了代碼的耦合度,fallback屬性指定了降級兜底的方法,代碼如下:

        此時再次訪問接口,雖然有異常,但是返回的確實降級兜底方法中的返回信息,如下圖:

        到了這里基本滿足了異常降級的處理需求,但是仍然有個疑問:能否只用一個方法處理全部的異常?

        答案是:,必須能,此時就要用到defaultFallback這個屬性了,指定默認的降級兜底方法,此時的業(yè)務(wù)方法變成如下代碼:

        defaultFallback屬性指定了默認的降級兜底方法,這個方法代碼如下:

        好了,異常降級處理到這兒已經(jīng)介紹完了,但是仍然有一個問題:若 blockHandler 和 fallback 都進行了配置,那么哪個會生效?

        結(jié)論:若 blockHandler 和 fallback 都進行了配置,則被限流降級而拋出 BlockException 時只會進入 blockHandler 處理邏輯。若未配置 blockHandler、fallbackdefaultFallback,則被限流降級時會將 BlockException 直接拋出。

        createOrder這個業(yè)務(wù)接口改造一下,同時指定blockHandler和fallback,代碼如下:

        此時不配置任何規(guī)則,直接訪問接口,可以看到這里直接進入了異常降級處理,如下圖:

        我們對createOrder這個資源配置降級規(guī)則:60秒內(nèi)如果出現(xiàn)2個以上的異常直接限流,如下圖:

        此時我們再次訪問這個接口,可以看到前兩次直接進入了fallback指定的方法中(并未達到限流的異常數(shù)閾值),兩次之后就被限流了,進入了blockHandler方法中,效果如下圖:

        上述源碼在sentinel-openfeign-provider9009這個模塊中,源碼獲取方式見文末。

        13、sentinel的黑白名單如何設(shè)置?

        顧名思義,黑名單就是拉黑唄,拉黑就是不能訪問了唄,sentinel能夠針對請求來源進行是否放行,若配置白名單則只有請求來源位于白名單內(nèi)時才可通過;若配置黑名單則請求來源位于黑名單時不通過,其余的請求通過。

        sentinel控制臺對應(yīng)得規(guī)則配置如下圖:

        該規(guī)則對應(yīng)得源碼為com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule,幾個屬性如下:

        • resource:資源名,即限流規(guī)則的作用對象。
        • limitApp:對應(yīng)的黑名單/白名單,不同 origin 用 , 分隔,如 appA,appB。
        • strategy:限制模式,AUTHORITY_WHITE 為白名單模式,AUTHORITY_BLACK 為黑名單模式,默認為白名單模式。

        官方文檔:https://github.com/alibaba/Sentinel/wiki/%E9%BB%91%E7%99%BD%E5%90%8D%E5%8D%95%E6%8E%A7%E5%88%B6

        這里有個問題:請求來源是什么,怎么獲???

        Sentinel提供了一個接口RequestOriginParser,我們可以實現(xiàn)這個接口根據(jù)自己業(yè)務(wù)的規(guī)則解析出請求來源名稱。

        下面我以IP作為區(qū)分請求來源,代碼如下:

        然后將127.0.0.1設(shè)置為黑名單,如下圖:

        直接訪問:http://127.0.0.1:9009/sentinel/rate/order/query?id=1002,結(jié)果如下圖:

        可以看到被限流了哦.................

        好了,黑白名單就介紹到這里。

        上述源碼在sentinel-openfeign-provider9009這個模塊中,源碼獲取方式見文末。

        14、限流規(guī)則如何持久化?

        Sentinel默認限流規(guī)則是存儲在內(nèi)存中,只要服務(wù)重啟之后對應(yīng)得限流規(guī)則也會消失,實際的生產(chǎn)中肯定是不允許這種操作,因此限流規(guī)則的持久化迫在眉睫。

        sentinel官方文檔提供了兩種持久化模式,分別如下:

        但是官方推薦使用Push模式,下面陳某就Push模式介紹一下持久化限流規(guī)則。這里使用Nacos作為配置中心。

        盜用官方一張架構(gòu)圖,如下:

        1、添加依賴

        這里需要添加一個依賴,如下:

        <dependency>
        ??????<groupId>com.alibaba.cspgroupId>
        ??????<artifactId>sentinel-datasource-nacosartifactId>
        dependency>

        2、配置文件中配置相關(guān)信息

        既然使用到了Nacos作為配置中心,肯定是要配置相關(guān)的地址、dataId...

        application.yml配置文件中添加如下配置:

        spring:
        ??cloud:
        ????sentinel:
        ??????##?nacos持久化配置
        ??????datasource:
        ????????##?配置流控規(guī)則,名字任意
        ????????ds-flow:
        ??????????nacos:
        ????????????##?nacos的地址
        ????????????server-addr:?127.0.0.1:8848
        ????????????##?配置ID
        ????????????dataId:?${spring.application.name}-flow
        ????????????##?配置分組,默認是DEFAULT_GROUP
        ????????????groupId:?DEFAULT_GROUP
        ????????????##?配置存儲的格式
        ????????????data-type:?json
        ????????????##?rule-type設(shè)置對應(yīng)得規(guī)則類型,總共七大類型,在com.alibaba.cloud.sentinel.datasource.RuleType這個枚舉類中有體現(xiàn)
        ????????????rule-type:?flow
        ????????##?配置降級規(guī)則,名字任意
        ????????ds-degrade:
        ??????????nacos:
        ????????????##?nacos的地址
        ????????????server-addr:?127.0.0.1:8848
        ????????????##?配置ID
        ????????????dataId:?${spring.application.name}-degrade
        ????????????##?配置分組,默認是DEFAULT_GROUP
        ????????????groupId:?DEFAULT_GROUP
        ????????????##?配置存儲的格式
        ????????????data-type:?json
        ????????????##?rule-type設(shè)置對應(yīng)得規(guī)則類型,總共七大類型,在com.alibaba.cloud.sentinel.datasource.RuleType這個枚舉類中有體現(xiàn)
        ????????????rule-type:?degrade

        上述配置僅僅展示了和持久化相關(guān)的一些配置,其他相關(guān)的配置代碼就不貼了,稍后自己看源碼。

        spring.cloud.sentinel.datasource下可以配置多個規(guī)則,陳某這里只配置了限流和降級規(guī)則,其他規(guī)則自己嘗試配一下,不同規(guī)則通過rule-type區(qū)分,其取值都在com.alibaba.cloud.sentinel.datasource.RuleType這個枚舉類中,對應(yīng)著sentinel中的幾大統(tǒng)計規(guī)則。

        3、在Nacos添加對應(yīng)的規(guī)則配置

        上述配置中對應(yīng)的限流(flow)規(guī)則如下圖:

        上述配置中對應(yīng)的降級(degrade)規(guī)則如下圖:

        先不糾結(jié)JSON數(shù)據(jù)里面到底是什么,先看效果,全部發(fā)布之后,Nacos中總共有了兩個配置,如下圖:

        上圖中可以看到我們的兩種規(guī)則已經(jīng)在Nacos配置好了,來看一下sentinel中是否已經(jīng)生效了,如下圖:

        哦了,已經(jīng)生效了,由于是push模式,只要nacos中點擊發(fā)布配置,相關(guān)規(guī)則配置就會推送到sentinel中。

        上述源碼在sentinel-openfeign-provider9009這個模塊中,源碼獲取方式見文末。

        伏筆:push模式只能保證Nacos中的修改推送到sentinel控制臺,**但是sentinel控制臺的限流規(guī)則修改如何推送到Nacos呢?**別著急,下面將會介紹..............

        4、JSON中到底怎么寫?

        很多人好奇JOSN中的配置到底怎么寫?其實很簡單,陳某在介紹各種規(guī)則的時候都明確告訴你每種規(guī)則對應(yīng)源碼中的實現(xiàn)類,比如流控規(guī)則對應(yīng)的類就是com.alibaba.csp.sentinel.slots.block.flow.FlowRule,JOSN中各個屬性也是來源于這個類。

        下面陳某列出各個規(guī)則的JSON配置,開發(fā)中照著改即可。

        1、流控規(guī)則

        [
        ??{
        ????//?資源名
        ????"resource":?"/test",
        ????//?針對來源,若為?default?則不區(qū)分調(diào)用來源
        ????"limitApp":?"default",
        ????//?限流閾值類型(1:QPS;0:并發(fā)線程數(shù))
        ????"grade":?1,
        ????//?閾值
        ????"count":?1,
        ????//?是否是集群模式
        ????"clusterMode":?false,
        ????//?流控效果(0:快速失敗;1:Warm?Up(預(yù)熱模式);2:排隊等待)
        ????"controlBehavior":?0,
        ????//?流控模式(0:直接;1:關(guān)聯(lián);2:鏈路)
        ????"strategy":?0,
        ????//?預(yù)熱時間(秒,預(yù)熱模式需要此參數(shù))
        ????"warmUpPeriodSec":?10,
        ????//?超時時間(排隊等待模式需要此參數(shù))
        ????"maxQueueingTimeMs":?500,
        ????//?關(guān)聯(lián)資源、入口資源(關(guān)聯(lián)、鏈路模式)
        ????"refResource":?"rrr"
        ??}
        ]

        2、降級規(guī)則

        [
        ??{
        ???//?資源名
        ????"resource":?"/test1",
        ????"limitApp":?"default",
        ????//?熔斷策略(0:慢調(diào)用比例,1:異常比率,2:異常計數(shù))
        ????"grade":?0,
        ????//?最大RT、比例閾值、異常數(shù)
        ????"count":?200,
        ????//?慢調(diào)用比例閾值,僅慢調(diào)用比例模式有效(1.8.0?引入)
        ????"slowRatioThreshold":?0.2,
        ????//?最小請求數(shù)
        ????"minRequestAmount":?5,
        ????//?當(dāng)單位統(tǒng)計時長(類中默認1000)
        ????"statIntervalMs":?1000,
        ????//?熔斷時長
        ????"timeWindow":?10
        ??}
        ]

        3、熱點規(guī)則

        [
        ??{
        ???//?資源名
        ????"resource":?"/test1",
        ????//?限流模式(QPS?模式,不可更改)
        ????"grade":?1,
        ????//?參數(shù)索引
        ????"paramIdx":?0,
        ????//?單機閾值
        ????"count":?13,
        ????//?統(tǒng)計窗口時長
        ????"durationInSec":?6,
        ????//?是否集群?默認false
        ????"clusterMode":?默認false,
        ????//?
        ????"burstCount":?0,
        ????//?集群模式配置
        ????"clusterConfig":?{
        ??????//?
        ??????"fallbackToLocalWhenFail":?true,
        ??????//?
        ??????"flowId":?2,
        ??????//?
        ??????"sampleCount":?10,
        ??????//?
        ??????"thresholdType":?0,
        ??????//?
        ??????"windowIntervalMs":?1000
        ????},
        ????//?流控效果(支持快速失敗和勻速排隊模式)
        ????"controlBehavior":?0,
        ????//?
        ????"limitApp":?"default",
        ????//?
        ????"maxQueueingTimeMs":?0,
        ????//?高級選項
        ????"paramFlowItemList":?[
        ??????{
        ???????//?參數(shù)類型
        ????????"classType":?"int",
        ???????//?限流閾值
        ????????"count":?222,
        ???????//?參數(shù)值
        ????????"object":?"2"
        ??????}
        ????]
        ??}
        ]

        4、系統(tǒng)規(guī)則

        負值表示沒有閾值檢查。不需要刪除參數(shù)

        [
        ??{
        ???//?RT
        ????"avgRt":?1,
        ????//?CPU?使用率
        ????"highestCpuUsage":?-1,
        ????//?LOAD
        ????"highestSystemLoad":?-1,
        ????//?線程數(shù)
        ????"maxThread":?-1,
        ????//?入口?QPS
        ????"qps":?-1
        ??}
        ]

        5、授權(quán)規(guī)則

        [
        ??{
        ????//?資源名
        ????"resource":?"sentinel_spring_web_context",
        ???//?流控應(yīng)用
        ????"limitApp":?"/test",
        ????//?授權(quán)類型(0代表白名單;1代表黑名單。)
        ????"strategy":?0
        ??}
        ]

        注意:對于上述JOSN中的一些可選屬性不需要的時候可以刪除。

        官方文檔:https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel

        15、限流規(guī)則如何推送到Nacos進行持久化?

        sentinel默認的持久化只能從nacos推送到sentinel控制臺,但是實際生產(chǎn)中肯定是雙向修改都能推送的,這個如何解決呢?

        其實sentinel官方文檔就有說到解決方法,不過需要自己修改sentinel控制臺的源碼來實現(xiàn)。

        這個還是比較復(fù)雜的,sentinel只幫我們實現(xiàn)了流控規(guī)則的demo,其他的還是要自己修改,這點不太人性化....

        在這之前需要自己下載對應(yīng)版本的sentinel控制臺的源碼,地址:https://github.com/alibaba/Sentinel/tags

        流控規(guī)則源碼修改

        在源碼的test目錄下有sentinel提供的demo,分別有apollo、nacos、zookeeper,如下圖:

        這里我們是Nacos,因此只需要nacos包下面的demo。修改步驟如下:

        1、去掉sentinel-datasource-nacos依賴的scop

        這個sentinel-datasource-nacos依賴默認是test,因此我們需要去掉這個,如下:


        <dependency>
        ???????<groupId>com.alibaba.cspgroupId>
        ???????<artifactId>sentinel-datasource-nacosartifactId>
        dependency>

        如果你集成的zookeeper或者apollo,則把相應(yīng)的依賴也要修改。

        2、復(fù)制test環(huán)境下的nacos整個包到main下

        將這個nacos包復(fù)制到com.alibaba.csp.sentinel.dashboard.rule這個包下,如下圖:

        3、將FlowControllerV2中的代碼復(fù)制到FlowControllerV1中

        com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2這個是sentinel提供的demo,只需要將其中的代碼全部覆蓋到com.alibaba.csp.sentinel.dashboard.controller.FlowControllerV1中。

        4、修改FlowControllerV1中的代碼

        直接覆蓋掉當(dāng)然不行,還要做一些修改,如下:

        • 修改RequestMapping中的請求url為/v1/flow
        • 修改ruleProvider、rulePublisher的依賴,修改后的代碼如下:
        ?@Autowired
        ????//使用nacos的依賴
        ????@Qualifier("flowRuleNacosProvider")
        ????private?DynamicRuleProvider>?ruleProvider;
        ????@Autowired
        ????//使用nacos的依賴
        ????@Qualifier("flowRuleNacosPublisher")
        ????private?DynamicRulePublisher>?rulePublisher;

        5、注意nacos的相關(guān)配置

        com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil這個工具類中對應(yīng)的是限流規(guī)則在nacos中的一些配置項,有groupId、dataId...對應(yīng)的配置如下:

        需要兩邊統(tǒng)一,可以自己修改。

        com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfig這個類中有個方法如下圖:

        默認指定的nacos地址是本地的,這個需要修改。

        6、完成

        以上步驟已經(jīng)改造了sentinel控制臺的流控規(guī)則,打包啟動控制臺代碼,命令如下:

        mvn?clean?install?-DskipTests=true?-pl?sentinel-dashboard?-am

        啟動后在控制臺添加流控規(guī)則,可以看到也會同步推送到nacos,包括增刪改。

        其他規(guī)則修改也很簡單,照葫蘆畫瓢,這里就不再詳細說了,后面會單獨出一篇文章詳細說一下。

        16、集群流控如何做?

        首先一個簡單的問題:為什么需要集群流控?單機流控不香嗎?原因如下:

        • 對于微服務(wù)要想保證高可用,必須是集群,假設(shè)有100個集群,那么想要設(shè)置流控規(guī)則,是不是每個微服務(wù)都要設(shè)置一遍?維護成本太高了
        • 單體流控還會造成流量不均勻的問題,出現(xiàn)總流控閾值沒有達到某些微服務(wù)已經(jīng)被限流了,這個是非常糟糕的問題,因此實際生產(chǎn)中對于集群不推薦單體流控。

        那么如何解決上述的問題呢?sentinel為我們提供了集群流控的規(guī)則。思想很簡單就是提供一個專門的server來統(tǒng)計調(diào)用的總量,其他的實例都與server保持通信。

        集群流控可以精確地控制整個集群的調(diào)用總量,結(jié)合單機限流兜底,可以更好地發(fā)揮流量控制的效果。

        集群流控中共有兩種身份:

        • Token Client:集群流控客戶端,用于向所屬 Token Server 通信請求 token。集群限流服務(wù)端會返回給客戶端結(jié)果,決定是否限流。
        • Token Server:即集群流控服務(wù)端,處理來自 Token Client 的請求,根據(jù)配置的集群規(guī)則判斷是否應(yīng)該發(fā)放 token(是否允許通過)。

        sentinel的集群限流有兩種模式,分別如下:

        • 獨立模式(Alone):即作為獨立的 token server 進程啟動,獨立部署,隔離性好,但是需要額外的部署操作。獨立模式適合作為 Global Rate Limiter 給集群提供流控服務(wù)。
        • 嵌入模式(Embedded):即作為內(nèi)置的 token server 與服務(wù)在同一進程中啟動。在此模式下,集群中各個實例都是對等的,token server 和 client 可以隨時進行轉(zhuǎn)變,因此無需單獨部署,靈活性比較好。但是隔離性不佳,需要限制 token server 的總 QPS,防止影響應(yīng)用本身。嵌入模式適合某個應(yīng)用集群內(nèi)部的流控。

        下面就以嵌入模式為例介紹一下如何配置。

        就以sentinel-openfeign-provider9009這個模塊作為演示,直接啟動三個集群,端口分別為9009、9011、9013,如下圖:

        啟動成功,在sentinel控制臺將會看到有三個實例已經(jīng)被監(jiān)控了,如下圖:

        此時只需要在控制臺指定一個服務(wù)為token server,其他的為token client,集群流控->新增token server,操作如下圖:

        選取一個作為服務(wù)端,另外兩個作為客戶端,此時就已經(jīng)配置好了,如下圖:

        此時就可以添加集群流控規(guī)則了,可以在sentinel控制臺直接添加,也可以通過Nacos直接配置,下圖是通過Nacos配置的,如下圖:

        Nacos推送成功后將會在sentinel控制臺看到這條流控規(guī)則的配置,如下圖:

        OK,至此集群流控到這兒就介紹完了,配置好之后可以自己試一下效果,陳某就不再演示了。

        官方文檔:https://github.com/alibaba/Sentinel/wiki/%E9%9B%86%E7%BE%A4%E6%B5%81%E6%8E%A7

        17、網(wǎng)關(guān)限流如何配置?

        這一塊內(nèi)容在后續(xù)介紹到網(wǎng)關(guān)的時候會詳細講,這里就不再細說了,有想要了解的可以看官方文檔。

        官方文檔:https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81

        18、整合openFeign如何實現(xiàn)熔斷降級?

        這個在上篇openFeign的文章中有詳細介紹:openFeign奪命連環(huán)9問,這誰受得了?這里就不再重復(fù)介紹了,有不知道的可以看上面這篇文章

        瀏覽 100
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        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>
            国产亲子乱视频看 | 天天射天天天天射天天射天天 | 精品精品精品 | 日韩精品成人 | 日韩欧美人人爽夜夜爽 | 中文字幕在线免费观看 | 思思热在线观看视频 | 久久久精品欧美 | 美女毛茸茸的阴户视频 | 成人美女视频 |