spring cloud alibaba sentinel 流控,服務降級,服務熔斷組件

一、 sentinel 主要特性

二、sentinel 的下載及安裝

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

下載  sentinel-dashboard-1.7.0.jar  前提是  java8環境OK,8080端口未被佔用。

啓動 sentinel , java  -jar  sentinel-dashboard-1.7.0.jar 

訪問 localhost:8080 ,賬號密碼均爲 sentinel。

三 、創建項目

(1)向 pom文件中 添加相關依賴 : 

  <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--    後續做持久化用到    -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--   sentinel     -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

修改  application.yml 配置文件

server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery: #Nacos註冊中心地址
        server-addr: localhost:8848
    sentinel:
      transport: #dashboard地址
        dashboard: localhost:8080
        port: 8719  #默認端口,如果被佔用則從8719依次+1掃描
      datasource:
        dsl:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data_type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: "*"

編寫 controller 

@RestController
@Slf4j
public class FlowLimitController {

    @GetMapping("/testA")
    public String testA(){
        try {
            TimeUnit.MILLISECONDS.sleep(800);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "---------testA";
    }

    @GetMapping("/testB")
    public String testB(){
        return "----------testB";
    }

}

 

(2)啓動 nacos  ,服務註冊到 nacos 中,然後啓動 sentinel 8080,最後啓動微服務,發現 sentinel 中空空如也,因爲 sentinel採用的是 懶加載,當訪問過了一次接口之後 纔會有監控數據展示到 控制檯上。

 四、流控規則

 直接 - 》 快速失敗 : 選擇 qps 時,當一秒內請求數達到閾值就會直接響應失敗,當選擇線程數時候,一秒內,超過一個線程訪問testA接口時,就會直接響應失敗。

關聯 -》 快速失敗

當請求 關聯 資源接口  B流量過大時,接口A直接快速響應失敗。

(3)Warm Up

 如下例子: 單機閾值爲10,預熱時長5s, 一開始 qps 爲 10/ 3 = 3,慢慢的過了5s之後 qps 就會變爲10.

 

秒殺系統:在開啓的瞬間,會有很多流量上來,很有可能把系統打死, 預熱方式就是爲了保護系統,慢慢的把流量放進來,慢慢的把閾值增長到設置的閾值。

均勻排隊:

 五、服務降級

 

 六、熱點key限流

  @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) {
        return "-------testHotKey";
    }

    public String deal_testHotKey(String p1, String p2,
                             BlockException exception){
        return "----deal_testHotKey,o(╥﹏╥)o";

    }

表示訪問testHotKey的資源,帶有第一個參數的情況下,並且閾值在1秒內達到了1次就會限流,自動調用 blockHandler 的值對應的方法並返回數據。相當於 將 返回的服務降級信息進行了自定義。

參數例外項: 當進行了如下配置的時候,代表p1 !=5 的情況下,每秒1次就會達到閾值,但是當p1 = 5的情況下,閾值每秒可以達到 200 ,注意熱點參數的類型必須是 基本類型或者String

@SentinelResource 處理的是Sentinel 控制檯配置的違規情況,由blockHandler 配置的方法進行兜底處理。

RuntimeException 

int age = 10 /0 , java運行時爆出的java運行時異常,@SentinelResource 不會處理,

@SentinelResource 主管配置出錯,運行出錯該走異常走異常。

七、系統規則 

針對整個系統的 第一道 防線

 八、服務降級處理提取類

package springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.springcloud.entities.CommonResult;
import com.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import springcloud.myhandler.CustomerBlockHandler;

@RestController
public class RateLimitController {

    @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 服務不可用");
    }

    @GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl",blockHandlerClass = CustomerBlockHandler.class,
    blockHandler = "handlerException")
    public CommonResult byUrl(){
        return new CommonResult(200,"按url限流測試OK", new Payment(2020L, "serial001"));
    }

    //CustomerBlockHandler
    @GetMapping("/rateLimit/CustomerBlockHandler")
    @SentinelResource(value = "CustomerBlockHandler",blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handlerException2")
    public CommonResult CustomerBlockHandler(){
        return new CommonResult(200,"按客戶自定義限流測試OK", new Payment(2020L, "serial003"));
    }

}
package springcloud.myhandler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.springcloud.entities.CommonResult;
import com.springcloud.entities.Payment;

public class CustomerBlockHandler {

    public static CommonResult handlerException(BlockException exception) {
        return new CommonResult(4444, "按客戶自定義,global handlerException", new Payment(2020L, "serial0003"));
    }
    public static CommonResult handlerException2(BlockException exception) {
        return new CommonResult(4444, "按客戶自定義2,global handlerException", new Payment(2020L, "serial0003"));
    }
}

使業務和代碼 耦合度解耦,避免了代碼的膨脹。

九、服務熔斷 異常忽略 exceptionsToIgnore

十、熔斷框架比較

 十一、sentinel 持久化規則

一旦我們重啓應用,sentinel 規則將消失,生產環境需要將配置規則進行持久化。

將限流配置規則持久化進nacos 保存,只要不刪除nacos中對 限流的配置規則,就不會消失。

主要需要用到 以下依賴:

修改 pom.xml

<!--    後續做持久化用到    -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

修改 application.yml配置文件

 在 nacos 中添加 規則配置:

配置解析:

  [{

 "resource": "/rateLimit/byUrl",

 "limitApp": "default",

 "grade":1,

"count": 1,

"strategy":0,

"controlBehavior":0,

"clusterMode": false

}] 


resource : 資源名稱
limitApp: 來源應用,
grade: 閾值類型,0表示線程數,1表示QPS
count: 單機閾值,
strategy: 流控模式,0表示直接,1表示關聯,2表示鏈路
controlBehavior: 流控效果,0表示快速失敗,1表示Warm Up ,2表示排隊等待
clusterMode: 是否集羣

服務停止之後,發現sentinel 中的 鏈路配置的限流又消失了,但是不用擔心,多次請求一下 在nacos 中配置了限流的 資源名稱,此時就會發現鏈路配置的限流數據又出現了。實現了限流配置的持久化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章