SpringCloudAlibaba入門之Sentinel(SCA)

我也有夢想呀發表於2022-04-08

微服務保護和熔斷降級技術Sentinel

1.微服務呼叫存在問題

由於一個服務不可用,有可能會導致一連串的微服務跟著不可用[伺服器支援的執行緒和併發數有限,請求一直阻塞,會導 致伺服器資源耗盡,從而導致所有其它服務都不可用], 形成級聯失敗,最終會導致服務雪崩問題。針對服務雪崩,有如 下幾種解決方案:

  • 方案 1:超時處理:設定超時時間,請求超過一定時間沒有響應就返回錯誤資訊,不會無休止等待
  • 方案 2: 倉壁模式, 倉壁模式來源於船艙的設計
  • 方案 3: 斷路器模式:由斷路器統計業務執行的異常比例,如果超出閾值則會熔斷該業務,攔截訪問該業務的一切請求。 斷路器會統計訪問某個服務的請求數量,異常比, 當發現訪問服務 D 的請求異常比例過高時,認為服務 D 有導致雪崩的 風險,會攔截訪問服務 D 的一切請求,形成熔斷
    image
  • 方案 4: 限流,流量控制:限制業務訪問的 QPS,避免服務因流量的突增而故障
    image

什麼是雪崩問題?

微服務之間相互呼叫,因為呼叫鏈中的⼀個服務故障,引起整個鏈路都無法訪問的情況。

限流是對服務的保護,避免因瞬間高併發流量而導致服務故障,進而避免雪崩。是⼀種預防措施。
超時處理、執行緒隔離、降級熔斷是在部分服務故障時,將故障控制在⼀定範圍,避免雪崩。是⼀種補救措施

2.前面整合了SpringCloud Hystrix實現了服務的降級,熔斷,限流.那Sentinel和Hystrix有什麼區別呢?

image

3.Sentinel 入門

①Sentinel安裝

我使用的是docker安裝方式,大家也可以自行用其他的方式.安裝好了以後直接在瀏覽器訪問:http://192.168.137.72:8858/
image

②Sentinel官網

https://sentinelguard.io/zh-cn/index.html

③流控、熔斷等都是針對簇點鏈路中的資源來設定的,因此我們可以點選對應資源後面的按鈕來設定規則

  • 流控:流量控制
  • 降級:降級熔斷
  • 熱點:熱點引數限流,是限流的⼀種
  • 授權:請求的許可權控制

④閾值型別

(1)測試QPS(Query Per Second):每秒請求數,就是說伺服器在一秒的時間內處理了多少個請求

image

快速重新整理頁面會出現下圖

image

(2)測試執行緒數流控:最大併發數是 3,超過 3 將直接流控,這裡我們藉助於 Jemeter 測試:。

image

Jemeter引數設定

image

image

image

測試結果

image

⑤流控模式

  • 直接:統計當前資源的請求,觸發閾值時對當前資源直接限流,也是預設的模式
  • 關聯:統計與當前資源相關的另一個資源,觸發閾值時,對當前資源限流
  • 鏈路:統計從指定鏈路訪問到本資源的請求,觸發閾值時,對指定鏈路限流

(1)在sentinel-consumer-user9001服務controller中新增兩個介面用於測試

@Value("${server.port}")
private String port;

@GetMapping("/findById")
public User findById(Integer id) {
	User user = userService.findById(id);
	return user;
}

@GetMapping("/write")
public String write() {
	return port;
}
設定關聯流控規則

image

Jemeter引數設定

image

測試結果

image

當兩個有競爭關係的資源 ⼀個優先順序較高,⼀個優先順序較低 ===> 可以使用關聯模式

注意:測試後面的規則,最好把前面的規則刪除掉,不然出現問題自己都蒙了......

⑥測試鏈路模式

(1)修改Service程式碼

@Override
@SentinelResource // Sentinel 預設只標記 Controller 中的方法為資源,如果要標記其它方法,需要利用@SentinelResource 註解
public void hello() {
	System.out.println("你好");
}

(2)修改Controller程式碼

 @GetMapping("/write")
public String write() {
	userService.hello();
	return port;
}

@GetMapping("/read")
public String read() {
	userService.hello();
	return port;
}

(3)修改yml配置檔案

sentinel:
      web-context-unify: false #如果不關閉,所有controller層的方法對service層呼叫都認為是同一個根鏈路

(4)設定流控規則

image

測試結果:

image

流控模式小結

  • 直接:對當前資源限流
  • 關聯:高優先順序資源觸發閾值,對低優先順序資源限流
  • 鏈路:閾值統計時,只統計從指定資源進入當前資源的請求,是對請求來源的限流

⑦流控效果

測試Warm up(預熱)流控模式:當系統執行時,有併發請求來訪問系統時,為了避免系統崩潰,可以設定一個閾值,讓專案可以處理請求的數量逐漸增加 到設定的閾值

image

測試結果:

image

測試 排隊等待:方式會嚴格控制請求通過的間隔 時間,也即是讓請求以均勻的速度通過,對應的是漏桶演算法.請求會進入佇列,按照閾值允許的時間間隔依次執行請求;如果請求預期等待時⻓大於超時時間,直接拒絕

編輯流控規則

image

修改程式碼
@GetMapping("/findById")
    public Movie findById(@RequestParam("id") Integer id){
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(port);
        return movieService.findById(id);
    }
測試結果:

image

⑧熱點 key 限流:是分別統計引數值相同的請求,判斷是 否超過 QPS 閾值。

新增請求介面

@SentinelResource(value = "hot")
@GetMapping("/resource/{hid}")
public String testHotResource(@PathVariable("hid") Long hid) {
	System.out.println(hid);
	return port;
}

修改熱點key規則,點選左側選單欄配置資訊更完善

image

引數為1時,每秒請求數最大為3
image

引數為2是,每秒請求數最大為5
image

雖然限流可以儘量避免因高併發而引起的服務故障,但服務還會因為其它原因而故障。而要將這些故障控制在一定範圍, 避免雪崩,就要靠執行緒隔離(艙壁模式)和熔斷降級手段了。 不管是執行緒隔離還是熔斷降級,都是對客戶端(呼叫方)的保護。

⑨執行緒隔離

執行緒隔離有兩種方式實現:

  • 1.執行緒池隔離 (Hystrix 兩種隔離方式都支援)
  • 2.訊號量隔離(Sentinel 只支援訊號量隔離)
    image

執行緒池隔離和訊號量隔離的區別:

image

執行緒池隔離與訊號量隔離各自的應用場景:

image

Hystrix 支援訊號量隔離與執行緒池隔離,預設使用的是執行緒池隔離,配置方式如下

hystrix: 
	command: 
		default: 
			execution: 
				isolation: 
					strategy: Thread # 預設是Thread, 可選Thread(執行緒池隔離)|Semaphore(訊號量隔離)

Sentinel 只支援訊號量隔離,配置方式如下

image

這裡的執行緒數是:該資源能使用用的 tomcat 執行緒數的最大值。也就是通過限制執行緒數量,實現艙壁模式。

執行緒隔離小結:

  • 執行緒隔離的兩種手段是?訊號量隔離、執行緒池隔離
  • 訊號量隔離的特點是?基於計數器模式,簡單,開銷小
  • 執行緒池隔離的特點是?基於執行緒池模式,有額外開銷,但隔離控制更強

⑩熔斷降級

sentinel 與 feign 整合之方式⼀:FallbackClass,無法對遠端呼叫的異常做處理

(1)修改ymlp配置檔案
feign:
  sentinel:
    enabled: true # 開啟feign對sentinel的支援
(2)編寫一個降級類,實現遠端呼叫的介面
package com.qbb.cloud2022.feign;

import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;
import org.springframework.stereotype.Component;

/**
 * @author QiuQiu&LL (個人部落格:https://www.cnblogs.com/qbbit)
 * @version 1.0
 * @date 2022-04-07  23:34
 * @Description:
 */
@Component
public class FeignMovieServiceFallBack implements FeignMovieService {
    @Override
    public Movie findById(Integer id) {
        Movie movie = new Movie(-1, "網路異常,請稍後再試~~~~");
        return movie;
    }
}

(3)在遠端呼叫的介面上新增屬性
@FeignClient(value = "sentinel-provider-user9101",fallback = FeignMovieServiceFallBack.class)
測試一下:

image

sentinel 與 feign 整合之方式二:FallbackFactory,可以對遠端呼叫的異常做處理,我們選擇這種

(1)修改ymlp配置檔案
feign:
  sentinel:
    enabled: true # 開啟feign對sentinel的支援
(2)建立一個Factory類實現FallBackFactory介面
package com.qbb.cloud2022.feign;

import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

/**
 * @author QiuQiu&LL (個人部落格:https://www.cnblogs.com/qbbit)
 * @version 1.0
 * @date 2022-04-07  23:34
 * @Description:
 */
@Component
public class FeignMovieServiceFallBackFactory implements FallbackFactory {
    @Override
    public Object create(Throwable throwable) {
        throwable.printStackTrace();
        return new Movie(-1, "網路異常,請稍後再試~~~~");
    }
}

(3)在遠端呼叫的介面上新增屬性
@FeignClient(value = "sentinel-provider-user9101",fallbackFactory = FeignMovieServiceFallBackFactory.class)
測試一下:

image
控制檯直接報錯
image

熔斷器的三種狀態

熔斷降級是解決雪崩問題的重要手段。其思路是由斷路器統計服務呼叫的異常比例、慢請求比例,如果超出閾值則會熔 斷該服務。即攔截訪問該服務的一切請求;而當服務恢復時,斷路器會放行訪問該服務的請求

image

斷路器熔斷策略有三種:慢呼叫、異常比例、異常數
image

上圖的意思是:RT 超過 500ms 的呼叫是慢呼叫,如果請求量超過 10 次,並且慢呼叫比例不低於 0.5,則觸發熔斷,熔斷時長為 5 秒。然後進入 half-open 狀態,放行一次請求做測試
修改被呼叫方的程式碼
@GetMapping("/findById")
    public Movie findById(@RequestParam("id") Integer id) {
        if (id == 2) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(port);
        return movieService.findById(id);
    }
測試一下:

image

Sentinel 熔斷降級的策略有哪些?

  • 慢呼叫比例:超過指定時⻓的呼叫為慢呼叫,統計單位時⻓內慢呼叫的比例,超過閾值則熔斷
  • 異常比例:統計單位時⻓內異常呼叫的比例,超過閾值則熔斷
  • 異常數:統計單位時⻓內異常呼叫的次數,超過閾值則熔斷

最後一個系統保護規則

系統規則包含下面幾個重要的屬性:

image

至此SpringCloudAlibaba入門之Sentinel配置完畢

相關文章