八、@SentinelResource

1、按名称限流+后续处理

参考上面的热点key步骤



springcloud alibaba与springcloud版本对应关系_限流



2、按照Url地址限流 + 后续处理

限流处理是sentinel自带的



springcloud alibaba与springcloud版本对应关系_限流_02



3、上面兜底方案面临的问题

同Hystrix一样

①、系统默认的,没有体现我们自己的业务要求

②、依照现有条件,我们自己定义的处理方法和业务代码耦合在一块,不直观

③、如果每个业务方法都添加一个兜底的,那代码膨胀加剧

④、全局统一的处理方法没有体现

4、客户自定义限流处理逻辑

①、创建 CustomerBlockHandler类用于自定义限流处理逻辑

②、自定义限流类



springcloud alibaba与springcloud版本对应关系_空指针异常_03



③、@SentinelResource上配置限流测处理类以及方法



springcloud alibaba与springcloud版本对应关系_持久化_04




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



九、服务熔断

1、sentinel整合ribbon+openFeign+fallback

2、Sentinel整合Ribbon演示

1)启动nacos和sentinel

2)服务提供者 cloudalibaba-provider-payment9003/9004

3)服务消费者 cloudalibaba-consumer-nacos-order84



springcloud alibaba与springcloud版本对应关系_持久化_05



代码放在gitee上:cloud2020: SpringCloud 和 SpringCloud Alibaba的demo

4)启动上述三个服务



springcloud alibaba与springcloud版本对应关系_cloud alibaba_06



5)添加 fallback 和 blockHandler,查看测试情况

①、目的

fallback管运行时异常

bolckHandler管配置违规

②、测试地址



springcloud alibaba与springcloud版本对应关系_持久化_07



③、不加任何配置



@RequestMapping("/consumer/fallback/{id}")
@SentinelResource(value = "fallback") //没有配置
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;
}



当没有任何配置时,返回给用户的就是Error页面



springcloud alibaba与springcloud版本对应关系_限流_08



④、只配置fallback



@RequestMapping("/consumer/fallback/{id}")
//@SentinelResource(value = "fallback") //没有配置
@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
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);
}




springcloud alibaba与springcloud版本对应关系_持久化_09



⑤、只配置 blockHandler



@RequestMapping("/consumer/fallback/{id}")
    //@SentinelResource(value = "fallback") //没有配置
    //@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
    @SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
    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);
    }



此时给fallback链路添加流控规则

快速点击fallback请求,会出现限流,但是不会对异常进行降级



springcloud alibaba与springcloud版本对应关系_限流_10




springcloud alibaba与springcloud版本对应关系_持久化_11



⑥、fallback和blockHandler都进行配置



@RequestMapping("/consumer/fallback/{id}")
//@SentinelResource(value = "fallback") //没有配置
//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
//@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler")
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);
}



4、Sentinel支持Feign

①、需要激活 sentinel对Feign的支持

在yml文件中配置



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



主启动类上添加 @EnableFeignClients

②、声明FeignClient



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

//feign的降级类
@Component
public class PaymentFallbackService implements PaymentService
{
    @Override
    public CommonResult<Payment> paymentSQL(Long id)
    {
        return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
    }
}



③、测试

将服务9003 9004停了,访问接口,会出现降级



springcloud alibaba与springcloud版本对应关系_空指针异常_12



十、规则持久化

1、是什么?

一旦我们重启应用(比如说上面的nacos8401服务),sentinel规则将会消失,生产环境需要将配置规则进行持久化

2、怎么玩?

将限流配置规则持久化进Nacos保存,只要刷新8401 某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel的流控规则持续有效

3、步骤

以nacos8401作为实例

1)修改nacos8401服务的pom文件

添加依赖



<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>



2)修改nacos8401服务的yml文件



sentinel:
    datasource:  #将流控规则持久化到nacos
      dsl:
        nacos:
          server-addr: localhost:8848
          dataId: cloudalibaba-sentinel-service
          groupId:  DEFAULT_GROUP
          data-type: json
          rule-type: flow



3)去nacos配置sentinel的持久化规则



springcloud alibaba与springcloud版本对应关系_限流_13




[
    {
        "resource": "/rateLimit/byUrl",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]




springcloud alibaba与springcloud版本对应关系_限流_14



4)启动nacos8401服务后,刷新sentinel发现配置的流控规则有了