Spring Cloud Alibaba學(xué)習(xí)(5)--- Sentinel與斷路器愧旦、系統(tǒng)保護(hù)、流量控制

雪崩問題

微服務(wù)調(diào)用鏈路中的某個服務(wù)故障碘举,引起整個鏈路中的所有微服務(wù)都不可用忘瓦,這就是雪崩
總結(jié):當(dāng)一個服務(wù)發(fā)生故障導(dǎo)致所有與它相關(guān)的鏈路都是不可以用的

image.png

解決雪崩方式

解決雪崩問題的常見方式有四種:

  1. 超時處理:設(shè)定超時時間搁廓,請求超過一定時間沒有響應(yīng)就返回錯誤信息引颈,不會無休止等待


    image.png
  2. 艙壁模式:限定每個業(yè)務(wù)能使用的線程數(shù)耕皮,避免耗盡整個tomcat的資源,因此也叫線程隔離蝙场。


    image.png
  3. 熔斷降級:由斷路器統(tǒng)計業(yè)務(wù)執(zhí)行的異常比例凌停,如果超出閾值則會熔斷該業(yè)務(wù),攔截訪問該業(yè)務(wù)的一切請求售滤。


    image.png
  4. 流量控制:限制業(yè)務(wù)訪問的QPS罚拟,避免服務(wù)因流量的突增而故障。


    image.png

Sentinel與Hystrix比較

我前面梳理了Hystrix的知識完箩,現(xiàn)在梳理的Sentinel與它的性質(zhì)是一樣的赐俗,都是對于服務(wù)的保護(hù),而現(xiàn)在Hystrix不再更新維護(hù)弊知,導(dǎo)致替代者Sentinel順應(yīng)市場需求


image.png

認(rèn)識Sentinel

Sentinel是阿里巴巴開源的一款微服務(wù)流量控制組件阻逮。官網(wǎng)地址:https://sentinelguard.io/zh-cn/index.html
Sentinel 具有以下特征:

  1. 豐富的應(yīng)用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發(fā)流量控制在系統(tǒng)容量可以承受的范圍)秩彤、消息削峰填谷叔扼、集群流量控制、實時熔斷下游不可用應(yīng)用等漫雷。
  2. 完備的實時監(jiān)控:Sentinel 同時提供實時的監(jiān)控功能瓜富。您可以在控制臺中看到接入應(yīng)用的單臺機(jī)器秒級數(shù)據(jù),甚至 500 臺以下規(guī)模的集群的匯總運行情況降盹。
  3. 廣泛的開源生態(tài):Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊与柑,例如與 Spring Cloud、Dubbo澎现、gRPC 的整合仅胞。您只需要引入相應(yīng)的依賴并進(jìn)行簡單的配置即可快速地接入 Sentinel。
  4. 完善的 SPI 擴(kuò)展點:Sentinel 提供簡單易用剑辫、完善的 SPI 擴(kuò)展接口干旧。您可以通過實現(xiàn)擴(kuò)展接口來快速地定制邏輯。例如定制規(guī)則管理妹蔽、適配動態(tài)數(shù)據(jù)源等椎眯。

安裝Sentinel

sentinel官方提供了UI控制臺,方便我們對系統(tǒng)做限流設(shè)置胳岂。大家可以在GitHub下載编整。


image.png

運行方式:

java -jar sentinel-dashboard-1.8.4.jar

賬號密碼以及登入方式是:
然后訪問:localhost:8080 即可看到控制臺頁面,默認(rèn)的賬戶和密碼都是sentinel

如果端口被占用:

java -jar sentinel-dashboard-1.8.4.jar -Dserver.port = 你輸入的端口號

其他常用參數(shù)如下:

image.png

整和微服務(wù)模塊

<!--sentinel  上面有父模塊所以不加版本號乳丰,沒有就需要加入版本號-->
<dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 #這個地址是你啟動Sentinel的地址掌测,本地啟動就是localhost或者是127.0.0.1 其他地方就是那個ip地址

查詢IP地址
win:

ipconfig

linux:

ifconfig

總結(jié):整和之后訪問任意接口都會觸發(fā)sentinel監(jiān)控

限流規(guī)則

簇點鏈路:
  1. 就是項目內(nèi)的調(diào)用鏈路,鏈路中被監(jiān)控的每個接口就是一個資源产园。默認(rèn)情況下sentinel會監(jiān)控SpringMVC的每一個端點(Endpoint)汞斧,因此SpringMVC的每一個端點(Endpoint)就是調(diào)用鏈路中的一個資源夜郁。
  2. 流控、熔斷等都是針對簇點鏈路中的資源來設(shè)置的粘勒,因此我們可以點擊對應(yīng)資源后面的按鈕來設(shè)置規(guī)則:


    image.png

    點擊資源/order/{orderId}后面的流控按鈕竞端,就可以彈出表單。表單中可以添加流控規(guī)則庙睡,如下圖所示:


    image.png
流控模式

在添加限流規(guī)則時事富,點擊高級選項,可以選擇三種流控模式:

  1. 直接:統(tǒng)計當(dāng)前資源的請求乘陪,觸發(fā)閾值時對當(dāng)前資源直接限流统台,也是默認(rèn)的模式
  2. 關(guān)聯(lián):統(tǒng)計與當(dāng)前資源相關(guān)的另一個資源,觸發(fā)閾值時啡邑,對當(dāng)前資源限流
  3. 鏈路:統(tǒng)計從指定鏈路訪問到本資源的請求饺谬,觸發(fā)閾值時,對指定鏈路限流
    image.png

    流控模式-關(guān)聯(lián)
  • 關(guān)聯(lián)模式:統(tǒng)計與當(dāng)前資源相關(guān)的另一個資源谣拣,觸發(fā)閾值時募寨,對當(dāng)前資源限流
  • 使用場景:比如用戶支付時需要修改訂單狀態(tài),同時用戶要查詢訂單森缠。查詢和修改操作會爭搶數(shù)據(jù)庫鎖拔鹰,產(chǎn)生競爭。業(yè)務(wù)需求是有限支付和更新訂單的業(yè)務(wù)贵涵,因此當(dāng)修改訂單業(yè)務(wù)觸發(fā)閾值時列肢,需要對查詢訂單業(yè)務(wù)限流。


    image.png

    當(dāng)/write資源訪問量觸發(fā)閾值時宾茂,就會對/read資源限流瓷马,避免影響/write資源。

流控模式-鏈路
鏈路模式:只針對從指定鏈路訪問到本資源的請求做統(tǒng)計跨晴,判斷是否超過閾值欧聘。
例如有兩條請求鏈路:

  • /test1 -> /common
  • /test2 -> /common
    如果只希望統(tǒng)計從/test2進(jìn)入到/common的請求,則可以這樣配置:


    image.png
  • Sentinel默認(rèn)只標(biāo)記Controller中的方法為資源端盆,如果要標(biāo)記其它方法怀骤,需要利用@SentinelResource注解,示例:
@SentinelResource("goods")
public void queryGoods() {
    System.err.println("查詢商品");
}
  • Sentinel默認(rèn)會將Controller方法做context整合焕妙,導(dǎo)致鏈路模式的流控失效蒋伦,需要修改application.yml,添加配
spring:
  cloud:
    sentinel:
      web-context-unify: false # 關(guān)閉context整合
流控效果

流控效果是指請求達(dá)到流控閾值時應(yīng)該采取的措施焚鹊,包括三種:

  • 快速失敽劢臁:達(dá)到閾值后,新的請求會被立即拒絕并拋出FlowException異常。是默認(rèn)的處理方式研叫。
  • warm up:預(yù)熱模式势决,對超出閾值的請求同樣是拒絕并拋出異常。但這種模式閾值會動態(tài)變化蓝撇,從一個較小值逐漸增加到最大閾值。
  • 排隊等待:讓所有的請求按照先后次序排隊執(zhí)行陈莽,兩個請求的間隔不能小于指定時長
    image.png

    流控效果-warm up
    warm up也叫預(yù)熱模式渤昌,是應(yīng)對服務(wù)冷啟動的一種方案。請求閾值初始值是 threshold / coldFactor走搁,持續(xù)指定時長后独柑,逐漸提高到threshold值。而coldFactor的默認(rèn)值是3.
    例如私植,我設(shè)置QPS的threshold為10忌栅,預(yù)熱時間為5秒,那么初始閾值就是 10 / 3 曲稼,也就是3索绪,然后在5秒后逐漸增長到10.
    image.png

    流控效果-排隊等待
    當(dāng)請求超過QPS閾值時,快速失敗和warm up 會拒絕新的請求并拋出異常贫悄。而排隊等待則是讓所有請求進(jìn)入一個隊列中瑞驱,然后按照閾值允許的時間間隔依次執(zhí)行。后來的請求必須等待前面執(zhí)行完成窄坦,如果請求預(yù)期的等待時間超出最大時長唤反,則會被拒絕。
    例如:QPS = 5鸭津,意味著每200ms處理一個隊列中的請求彤侍;timeout = 2000,意味著預(yù)期等待超過2000ms的請求會被拒絕并拋出異常
    image.png
熱點參數(shù)限流

之前的限流是統(tǒng)計訪問某個資源的所有請求逆趋,判斷是否超過QPS閾值剑令。而熱點參數(shù)限流是分別統(tǒng)計參數(shù)值相同的請求玩郊,判斷是否超過QPS閾值。


image.png

在熱點參數(shù)限流的高級選項中,可以對部分參數(shù)設(shè)置例外配置:


image.png

結(jié)合上一個配置岂贩,這里的含義是對0號的long類型參數(shù)限流,每1秒相同參數(shù)的QPS不能超過5谅辣,有兩個例外:
  • 如果參數(shù)值是2袄琳,則每1秒允許的QPS為10
  • 如果參數(shù)值是3,則每1秒允許的QPS為10
    注意:直接點擊熱點添加沒有高級選擇杆融,點擊熱點規(guī)則里面添加熱點規(guī)則才有高級選擇
    image.png

    image.png

    image.png

隔離和降級

雖然限流可以盡量避免因高并發(fā)而引起的服務(wù)故障楞卡,但服務(wù)還會因為其它原因而故障。而要將這些故障控制在一定范圍,避免雪崩蒋腮,就要靠線程隔離(艙壁模式)和熔斷降級手段了淘捡。
不管是線程隔離還是熔斷降級,都是對客戶端(調(diào)用方)的保護(hù)池摧。


image.png
Feign整合Sentinel

SpringCloud中焦除,微服務(wù)調(diào)用都是通過Feign來實現(xiàn)的,因此做客戶端保護(hù)必須整合Feign和Sentinel作彤。

  1. 修改OrderService的application.yml文件膘魄,開啟Feign的Sentinel功能
feign:
  sentinel:
    enabled: true # 開啟Feign的Sentinel功能
  1. 給FeignClient編寫失敗后的降級邏輯
  • 方式一:FallbackClass,無法對遠(yuǎn)程調(diào)用的異常做處理
  • 方式二:FallbackFactory竭讳,可以對遠(yuǎn)程調(diào)用的異常做處理创葡,我們選擇這種
@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
    @Override
    public UserClient create(Throwable throwable) {
        // 創(chuàng)建UserClient接口實現(xiàn)類,實現(xiàn)其中的方法绢慢,編寫失敗降級的處理邏輯
        return new UserClient() {
            @Override
            public User findById(Long id) {
                // 記錄異常信息
                log.error("查詢用戶失敗", throwable);
                // 根據(jù)業(yè)務(wù)需求返回默認(rèn)的數(shù)據(jù)灿渴,這里是空用戶
                return new User();
            }
        };
    }
}
線程隔離

線程隔離有兩種方式實現(xiàn):

  • 線程池隔離
  • 信號量隔離(Sentinel默認(rèn)采用)
    image.png

    image.png

    線程隔離(艙壁模式)
    在添加限流規(guī)則時,可以選擇兩種閾值類型:
    image.png
  • QPS:就是每秒的請求數(shù)胰舆,在上面說了
  • 線程數(shù):是該資源能使用用的tomcat線程數(shù)的最大值骚露。也就是通過限制線程數(shù)量,實現(xiàn)艙壁模式缚窿。
熔斷降級

熔斷降級是解決雪崩問題的重要手段荸百。其思路是由斷路器統(tǒng)計服務(wù)調(diào)用的異常比例、慢請求比例滨攻,如果超出閾值則會熔斷該服務(wù)够话。即攔截訪問該服務(wù)的一切請求;而當(dāng)服務(wù)恢復(fù)時光绕,斷路器會放行訪問該服務(wù)的請求女嘲。

image.png

熔斷策略-慢調(diào)用

斷路器熔斷策略有三種:慢調(diào)用、異常比例诞帐、異常數(shù)

  • 慢調(diào)用:業(yè)務(wù)的響應(yīng)時長(RT)大于指定時長的請求認(rèn)定為慢調(diào)用請求欣尼。在指定時間內(nèi),如果請求數(shù)量超過設(shè)定的最小數(shù)量停蕉,慢調(diào)用比例大于設(shè)定的閾值愕鼓,則觸發(fā)熔斷。例如:
    image.png

    解讀:RT超過500ms的調(diào)用是慢調(diào)用慧起,統(tǒng)計最近10000ms內(nèi)的請求菇晃,如果請求量超過10次,并且慢調(diào)用比例不低于0.5蚓挤,則觸發(fā)熔斷磺送,熔斷時長為5秒驻子。然后進(jìn)入half-open狀態(tài),放行一次請求做測試估灿。
熔斷策略-異常比例崇呵、異常數(shù)

斷路器熔斷策略有三種:慢調(diào)用、異常比例或異常數(shù)

  • 異常比例或異常數(shù):統(tǒng)計指定時間內(nèi)的調(diào)用馅袁,如果調(diào)用次數(shù)超過指定請求數(shù)域慷,并且出現(xiàn)異常的比例達(dá)到設(shè)定的比例閾值(或超過指定異常數(shù)),則觸發(fā)熔斷汗销。例如:
    image.png

    解讀:統(tǒng)計最近1000ms內(nèi)的請求犹褒,如果請求量超過10次,并且異常比例不低于0.5大溜,則觸發(fā)熔斷,熔斷時長為5秒估脆。然后進(jìn)入half-open狀態(tài)钦奋,放行一次請求做測試。

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

授權(quán)規(guī)則可以對調(diào)用方的來源做控制疙赠,有白名單和黑名單兩種方式付材。

  • 白名單:來源(origin)在白名單內(nèi)的調(diào)用者允許訪問
  • 黑名單:來源(origin)在黑名單內(nèi)的調(diào)用者不允許訪問


    image.png

例如,我們限定只允許從網(wǎng)關(guān)來的請求訪問order-service圃阳,那么流控應(yīng)用中就填寫網(wǎng)關(guān)的名稱

image.png

注意:在sentinel內(nèi)部有個RequestOriginParser內(nèi)部不能區(qū)別來源厌衔,只會返回Defaule需要自己配合過濾器來增加header里面的請求參數(shù)來判斷來源,總體來說就是根據(jù)你指定的來源才能訪問的性質(zhì)才能訪問你的接口捍岳,來起到保護(hù)的效果
代碼展現(xiàn):

@Component
public class SentinelOriginRequest implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String origin = httpServletRequest.getHeader("origin");
        if (StringUtils.isEmpty(origin)) {
            origin = "blank";
        }
        return origin;
    }
}

解讀:這里我實現(xiàn)了sentinel的RequestOriginParser這個類富寿,并且把這個對象變?yōu)榱私M件,在header里面加入了origin這個參數(shù)锣夹,如果攜帶了這個參數(shù)就返回這個參數(shù)代表允許

自定義異常結(jié)果

默認(rèn)情況下页徐,發(fā)生限流、降級银萍、授權(quán)攔截時变勇,都會拋出異常到調(diào)用方。如果要自定義異常時的返回結(jié)果贴唇,需要實現(xiàn)BlockExceptionHandler接口:

@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String msg = "未知異常";
        int status = 429;

        if (e instanceof FlowException) {
            msg = "請求被限流了";
        } else if (e instanceof ParamFlowException) {
            msg = "請求被熱點參數(shù)限流";
        } else if (e instanceof DegradeException) {
            msg = "請求被降級了";
        } else if (e instanceof AuthorityException) {
            msg = "沒有權(quán)限訪問";
            status = 401;
        }

        response.setContentType("application/json;charset=utf-8");
        response.setStatus(status);
        response.getWriter().println("{\"msg\": " + msg + ", \"status\": " + status + "}");
    }
}

而BlockException包含很多個子類搀绣,分別對應(yīng)不同的場景:


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市戳气,隨后出現(xiàn)的幾起案子链患,更是在濱河造成了極大的恐慌,老刑警劉巖瓶您,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锣险,死亡現(xiàn)場離奇詭異蹄皱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)芯肤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門巷折,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人崖咨,你說我怎么就攤上這事锻拘。” “怎么了击蹲?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵署拟,是天一觀的道長。 經(jīng)常有香客問我歌豺,道長推穷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任类咧,我火速辦了婚禮馒铃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痕惋。我一直安慰自己区宇,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布值戳。 她就那樣靜靜地躺著议谷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪堕虹。 梳的紋絲不亂的頭發(fā)上卧晓,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音赴捞,去河邊找鬼禀崖。 笑死,一個胖子當(dāng)著我的面吹牛螟炫,可吹牛的內(nèi)容都是我干的波附。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼昼钻,長吁一口氣:“原來是場噩夢啊……” “哼掸屡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起然评,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤仅财,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后碗淌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盏求,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡抖锥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了碎罚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磅废。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖荆烈,靈堂內(nèi)的尸體忽然破棺而出拯勉,到底是詐尸還是另有隱情,我是刑警寧澤憔购,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布宫峦,位于F島的核電站,受9級特大地震影響玫鸟,放射性物質(zhì)發(fā)生泄漏导绷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一屎飘、第九天 我趴在偏房一處隱蔽的房頂上張望妥曲。 院中可真熱鬧,春花似錦枚碗、人聲如沸逾一。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至箱玷,卻和暖如春怨规,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锡足。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工波丰, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舶得。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓掰烟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沐批。 傳聞我的和親對象是個殘疾皇子纫骑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容