@SentinelResource使用

1、@SentinelResource定義資源名

  1.1、修改CircleBreakerController中fallback方法,如下:

1 @RequestMapping("/consumer/fallback/{id}")
2 @SentinelResource(value = "fallback") // 沒有配置
3 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
4     ...
5 }

  1.2、重新啟動項目

  1.3、訪問地址http://localhost:7994/consumer/fallback/3,并在sentinel控制臺設置限流規則

    注意這里設置規則的時候,可以直接使用@SentinelResource的value作為資源名

    

  1.4、快速訪問地址http://localhost:7994/consumer/fallback/3,限流成功

    

2、@SentinelResource 中的fallback

  fallback負責業務異常和限流時處理

  2.1、修改CircleBreakerController中fallback方法,如下:

復制代碼
 1 @RequestMapping("/consumer/fallback/{id}")
 2 @SentinelResource(value = "fallback", fallback = "handlerFallback") // fallback負責業務異常和限流返回
 3 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
 4     ...
 5 }
 6 
 7 public CommonResult<Payment> handlerFallback(Long id, Throwable e) {
 8     Payment payment = new Payment(id, "null");
 9     return new CommonResult(500, "兜底異常處理handlerFallback,Exception內容:" + e.getMessage(), payment);
10 }  
復制代碼

  2.2、重新啟動項目

  2.3、訪問地址http://localhost:7994/consumer/fallback/4,出現異常由fallback指定的方法處理

    

  2.4、在sentinel控制臺設置限流規則,設置QPS為閥值為1

  2.5、快速訪問地址http://localhost:7994/consumer/fallback/3,限流成功,限流返回內容為fallback指定的方法

    

3、@SentinelResource 中的blockHandler

  blockHandler只負責sentinel控制臺配置違規

  3.1、修改CircleBreakerController中fallback方法,如下: 

復制代碼
 1 @RequestMapping("/consumer/fallback/{id}")
 2 @SentinelResource(value = "fallback", blockHandler = "blockHandler") // blockHander只負責sentinel控制臺配置違規
 3 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
 4     ...
 5 }
 6 
 7 public CommonResult<Payment> handlerFallback(Long id, Throwable e) {
 8     Payment payment = new Payment(id, "null");
 9     return new CommonResult(500, "兜底異常處理handlerFallback,Exception內容:" + e.getMessage(), payment);
10 }
11 
12 public CommonResult<Payment> blockHandler(Long id, BlockException blockException) {
13     Payment payment = new Payment(id, "null");
14     return new CommonResult(500, "blockHandler-Sentinel限流,Exception內容:" + blockException.getMessage(), payment);
15 } 
復制代碼

  3.2、重新啟動項目

  3.3、訪問地址http://localhost:7994/consumer/fallback/4,返回參數非法異常

  3.4、在sentinel控制臺設置限流規則,設置QPS為閥值為1

  3.4、快速訪問地址http://localhost:7994/consumer/fallback/3,限流成功,限流返回內容為blockHandler指定的方法

    

4、@SentinelResource 中的fallback和blockHandler同時存在

  fallback負責處理異常,blockHandler負責sentinel控制臺配置違規

  4.1、修改CircleBreakerController中fallback方法,如下:

1 @RequestMapping("/consumer/fallback/{id}")
2 @SentinelResource(value = "fallback", blockHandler = "blockHandler", fallback = "handlerFallback")
3 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
4     ...
5 }  

  4.2、重新啟動項目

  4.3、訪問地址http://localhost:7994/consumer/fallback/4,出現異常由fallback指定的方法處理

    

  4.4、在sentinel控制臺設置限流規則,設置QPS為閥值為1

  4.4、快速訪問地址http://localhost:7994/consumer/fallback/3,限流成功,限流返回內容為blockHandler指定的方法

    

5、@SentinelResource 中的exceptionsToIgnore

  排除fallback指定的方法不處理的異常

  5.1、修改CircleBreakerController中fallback方法,如下:

1 @RequestMapping("/consumer/fallback/{id}")
2 @SentinelResource(value = "fallback", blockHandler = "blockHandler", fallback = "handlerFallback",
3         exceptionsToIgnore = {IllegalArgumentException.class})
4 public CommonResult<Payment> fallback(@PathVariable("id") Long id) {
5     ...
6 }

  5.2、重新啟動項目

  5.3、訪問地址http://localhost:7994/consumer/fallback/4,出現參數異常直接顯示,fallback指定的方法不處理異常

    

本章介紹Sentinel 與OpenFeign整合使用,

項目框架

  

feign整合

  2、主要是修改項目:springcloud-consumer-sentinel-order7994服務(調用者),引入openfeign依賴

1 <!-- openfeign -->
2 <dependency>
3     <groupId>org.springframework.cloud</groupId>
4     <artifactId>spring-cloud-starter-openfeign</artifactId>
5 </dependency>

    

    注意版本問題,本例使用版本

1 <spring-boot.version>2.2.5.RELEASE</spring-boot.version>
2 <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
3 <spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>

    Hoxton.SR1 中,fegin.context接口方法的定義為parseAndValidatateMetadata
    Hoxton.SR3 中,fegin.context接口方法的定義為parseAndValidateMetadata

    由于com.alibaba.cloud.sentinel.feign.SentinelContractHolder類中使用了fegin.context接口方法,導致可能出現版本沖突,可能報錯:

    AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata

    所以在項目用需要引入2.2.1.RELEASE版的spring-cloud-starter-alibaba-sentinel,并排除com.fasterxml.jackson.dataformat依賴(避免返回xml內容)

復制代碼
 1 <!-- alibaba nacos sentinel -->
 2 <dependency>
 3     <groupId>com.alibaba.cloud</groupId>
 4     <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
 5     <version>2.2.1.RELEASE</version>
 6     <exclusions>
 7         <exclusion>
 8             <groupId>com.fasterxml.jackson.dataformat</groupId>
 9             <artifactId>jackson-dataformat-xml</artifactId>
10         </exclusion>
11     </exclusions>
12 </dependency>
復制代碼

  3、application.yml文件如下,激活Sentinel對Feign的支持:

# 端口
server:
  port: 7001
spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.186.128:8848
    sentinel:
      transport:
        # 配置dashboard地址
        dashboard: 192.168.186.128:8998
        # 應用與控制臺交互的端口 默認8719
        port: 8719
# 激活feign對sentinel的支持
feign:
  sentinel:
    enabled: true
management:
  endpoints:
    web:
      exposure:
        include: '*'

 

  4、主啟動,啟用OpenFeign

復制代碼
1 @SpringBootApplication
2 @EnableDiscoveryClient
3 @EnableFeignClients
4 public class OrderMain7994 {
5     public static void main(String[] args) {
6         SpringApplication.run(OrderMain7994.class, args);
7     }
8 }
復制代碼

  5、定義Feign接口,如下:

1 @FeignClient(value = "nacos-payment-provider", fallback = PaymentFallbackService.class)
2 public interface PaymentService {
3 
4     @GetMapping(value = "/paymentSQL/{id}")
5     public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
6 }

  6、定義Feign接口實現類,用于服務降級

復制代碼
1 @Component
2 public class PaymentFallbackService implements PaymentService{
3 
4     public CommonResult<Payment> paymentSQL(Long id) {
5         return new CommonResult<Payment>(500, "服務降級返回,----PaymentFallbackService-paymentSQL");
6     }
7 }
復制代碼

  7、編寫Controller,增加如下內容:

復制代碼
1     // =======OpenFeign
2     @Autowired
3     private PaymentService paymentService;
4 
5     @GetMapping(value = "/consumer/paymentSQL/{id}")
6     public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
7         return  paymentService.paymentSQL(id);
8     }
復制代碼

  8、測試

    1)啟動項目

    2)使用地址:http://localhost:7994/consumer/paymentSQL/3,正常獲取內容

      

    3)關閉服務提供者

    4)使用地址:http://localhost:7994/consumer/paymentSQL/3,服務降級

      

在使用Sentinel我們發現,只要重新啟動Sentinel的Java 客戶端服務,Sentinel控制臺配置的限流規則,就清空不存在了,下面介紹怎么持久化Sentinel規則

Sentinel 持久化規則

  本例介紹Sentinel從Nacos配置中心讀取應用的限流降級配置規則

  1、打開cloud-sentinel-service8401項目

  2、修改POM文件,增加依賴sentinel數據nacos,如下:

    <dependencies>

        <!--datasource-->
        <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>
        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

    </dependencies>

 

  3、修改application.yml文件,如下:

# 端口
server:
  port: 8401
spring:
  application:
    name: alibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.186.128:8848
    sentinel:
      transport:
        # 配置Sentinel DashBoard地址
        dashboard: 192.168.186.128:8998
        # 應用與Sentinel控制臺交互的端口,應用本地會起一個該端口占用的HttpServer
        # 默認8719端口,假如端口被占用,依次+1,直到找到未被占用端口
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: 192.168.186.128:8848
            dataId: alibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: '*'

 

  4、在Nacos配置中心,增加配置

    

    配置說明:

      1)resource:資源名稱;

      2)limitApp:來源應用;

      3)grade:閥值類型,0表示線程數,1表示QPS

      4)count:單機閥值;

      5)strategy:流控模式,0表示直接,1表示關聯,2表示鏈路;

      6)controlBehavior:流控效果,0表示快速失敗,1表示Warm Up,2表示排隊等待;

      7)clusterMode:是否集群

  5、啟動項目測試

    1)啟動項目

    2)快速訪問地址:http://localhost:8401/testB,服務被限流,Sentinel持久化規則已生效