SpringCloud Alibaba_Sentinel實現熔斷與限流

安裝Sentinel

sentinel組件由兩個部分組成:

  • 核心庫(Java客戶端),不依賴任何框架和庫,能夠運行於Java運行時環境,同時對SpringCloud等框架也有較好的支持。
  • 控制檯(DashBoard)基於SpringBoot開發,打包後可以直接運行,不需要額外的Tomcat等應用容器

下載

https://github.com/alibaba/Sentinel/releases

運行命令

java -jar sentinel-dashboard-1.7.2.jar

注意:8080端口不能被佔用

訪問sentinel管理界面

http://localhost:8080
賬號密碼:sentinel

流控規則

基本介紹

在這裏插入圖片描述

  • 資源名:唯一名稱,默認請求路徑
  • 針對來源:Sentinel可以針對調用者進行限流,填寫微服務名,默認default(不區分來源)
  • 閾值類型/單機閾值
    • QPS(每秒請求數量):當調用該api的QPS達到閾值的時候,進行限流
    • 線程數:當調用該api的線程數達到閾值的時候,進行限流
  • 是否集羣:不需要集羣
  • 流控模式:
    • 直接:api達到限流條件時,直接限流
      在這裏插入圖片描述
    • 關聯:當關聯的資源達到閾值時,就限流自己
      在這裏插入圖片描述
    • 鏈路:只記錄指定鏈路上的流量(指定資源從入口資源進來的流量,如果達到閾值,就進行限流)
  • 流控效果
    • 快速失敗:直接失敗。拋異常
    • Warm up:根據coldfactor(冷加載因子,默認3)的值,從閾值/coldfactor,經過預熱時長,才達到設置的QPS閾值
      在這裏插入圖片描述
      如:秒殺系統在開啓瞬間,會有很多流量上來,很可能把系統打死,預熱方式就是爲了保護系統,可慢慢的把流量放進來,慢慢的把閾值增長到設置的閾值。
    • 排隊等待:勻速排隊,讓請求以勻速通過,閾值類型必須設置爲QPS,否則無效
      在這裏插入圖片描述
      在這裏插入圖片描述

降級規則

RT

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

異常比例

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

異常數

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

熱點key限流

配置

在這裏插入圖片描述

@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                         @RequestParam(value = "p2",required = false) String p2)
{
    //int age = 10/0;
    return "------testHotKey";
}

返回異常不友好界面,blocked by sentinel

@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                         @RequestParam(value = "p2",required = false) String p2)
{
    //int age = 10/0;
    return "------testHotKey";
}
public String deal_testHotKey (String p1, String p2, BlockException exception)
{
    return "------deal_testHotKey,o(╥﹏╥)o";  //sentinel系統默認的提示:Blocked by Sentinel (flow limiting)
    }

自定義blockHandler,處理異常。

參數例外項

假如當p1的值等於5時,它的閾值可以達到200:
在這裏插入圖片描述
參數類型僅限於基本數據類型或者String

系統規則

在這裏插入圖片描述
在這裏插入圖片描述
系統配置管轄太寬泛,可能引起全局範圍內的問題,不使用,危險。

@SentinelResource

按照資源名稱+流控規則限流+後續處理

在這裏插入圖片描述

@GetMapping("/byResource")
@SentinelResource(value = "byResource",blockHandler = "handleException")
public CommonResult byResource()
{
    return new CommonResult(200,"按資源名稱限流測試OK",new Payment(2020L,"serial001"));
}
public CommonResult handleException(BlockException exception)
{
    return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服務不可用");
}

按照url+流控規則限流+後續處理

在這裏插入圖片描述

@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl")
public CommonResult byUrl()
{
    return new CommonResult(200,"按url限流測試OK",new Payment(2020L,"serial002"));
}

現階段問題

  • 系統默認,沒有體現特定的業務要求
  • 自定義Handler與業務邏輯耦合
  • 每個業務邏輯都需要獨自的兜底Handler,代碼膨脹
  • 沒有全局統一的處理方法

自定義限流處理邏輯

  • 自定義限流處理類
public class CustomerBlockHandler
{
    public static CommonResult handlerException(BlockException exception)
    {
        return new CommonResult(4444,"按客戶自定義,global handlerException----1");
    }
    public static CommonResult handlerException2(BlockException exception)
    {
        return new CommonResult(4444,"按客戶自定義,global handlerException----2");
    }
}
  • 修改@SentinelResource
@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
        blockHandlerClass = CustomerBlockHandler.class,
        blockHandler = "handlerException2")
public CommonResult customerBlockHandler()
{
    return new CommonResult(200,"按客戶自定義",new Payment(2020L,"serial003"));
}

服務熔斷

消費側Sentinel整合Ribbon+OpenFeign+FallBack

  • pom
<!--SpringCloud openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--SpringCloud ailibaba nacos -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  • yml
server:
  port: 84

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置Sentinel dashboard地址
        dashboard: localhost:8080
        #默認8719端口,假如被佔用會自動從8719開始依次+1掃描,直至找到未被佔用的端口
        port: 8719

#消費者將要去訪問的微服務名稱(註冊成功進nacos的微服務提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

# 激活Sentinel對Feign的支持
feign:
  sentinel:
    enabled: true

Ribbon

  • 配置RestTemplate
@Configuration
public class ApplicationContextConfig
{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}
  • 業務邏輯
@RequestMapping("/consumer/fallback/{id}")
//fallback只負責業務異常
//blockHandler只負責sentinel控制檯配置違規
@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
        exceptionsToIgnore = {IllegalArgumentException.class})
public CommonResult<Payment> fallback(@PathVariable Long id)
{
    CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id);

    if (id == 4) {
        throw new IllegalArgumentException ("IllegalArgumentException,非法參數異常....");
    }else if (result.getData() == null) {
        throw new NullPointerException ("NullPointerException,該ID沒有對應記錄,空指針異常");
    }

    return result;
}
//本例是fallback
public CommonResult handlerFallback(@PathVariable  Long id,Throwable e) {
    Payment payment = new Payment(id,"null");
    return new CommonResult<>(444,"兜底異常handlerFallback,exception內容  "+e.getMessage(),payment);
}
//本例是blockHandler
public CommonResult blockHandler(@PathVariable  Long id,BlockException blockException) {
    Payment payment = new Payment(id,"null");
    return new CommonResult<>(445,"blockHandler-sentinel限流,無此流水: blockException  "+blockException.getMessage(),payment);
}

OpenFeign

  • Service
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
public interface PaymentService
{
    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
  • FallBackService
@Component
public class PaymentFallbackService implements PaymentService
{
    @Override
    public CommonResult<Payment> paymentSQL(Long id)
    {
        return new CommonResult<>(44444,"服務降級返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
    }
}

  • Controller
@Resource
private PaymentService paymentService;

@GetMapping(value = "/consumer/paymentSQL/{id}")
@SentinelResource(value = "fallback",blockHandler = "blockHandler")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id)
{
    return paymentService.paymentSQL(id);
}

規則持久化

一旦重啓應用,sentinel規則消失,生產環境需要將配置規則進行持久化。
將限流規則持久進Nacos保存,只要刷新8401某個rest地址,sentinel控制檯的流控規則就能看得到,只要Nacos裏面的配置不刪除,針對8401上的流控規則持續有效

  • pom
<!--SpringCloud ailibaba nacos -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel-datasource-nacos 後續做持久化用到-->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  • yaml
server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服務註冊中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

management:
  endpoints:
    web:
      exposure:
        include: '*'

feign:
  sentinel:
    enabled: true # 激活Sentinel對Feign的支持
  • 添加Nacos業務規則配置
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章