• 十五、Sentinel的@SentinelResource(3)


    一、服务熔断功能

    1. Ribbon系列

    参考代码:码云 注意提交记录

    1.1 整体流程

    在这里插入图片描述

    1.2 配置

    1. 启动nacos和sentinel
    2. 服务提供者cloudalibaba-provider-payment9003/9004 配置和正常的服务提供者一样
    3. 测试所用的controller
    @RestController
    public class PaymentController
    {
        @Value("${server.port}")
        private String serverPort;
    
        public static HashMap<Long, Payment> hashMap = new HashMap<>();
        static{
            hashMap.put(1L,new Payment(1L,"28a8c1e3bc2742d8848569891fb42181"));
            hashMap.put(2L,new Payment(2L,"bba8c1e3bc2742d8848569891ac32182"));
            hashMap.put(3L,new Payment(3L,"6ua8c1e3bc2742d8848569891xt92183"));
        }
    
        @GetMapping(value = "/paymentSQL/{id}")
        public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
            Payment payment = hashMap.get(id);
            CommonResult<Payment> result = new CommonResult(200,"from mysql,serverPort:  "+serverPort,payment);
            return result;
        }
    }
    
    1. 消费端 cloudalibaba-consumer-nacos-order84
      主要配置
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
    
    server:
      port: 84
    
    spring:
      application:
        name: nacos-order-consumer
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
        sentinel:
          transport:
            dashboard: localhost:8080
            port: 8719
    
    service-url:
      nacos-user-service: http://nacos-payment-provider
    
    1. 消费端的controller
    @RestController
    @Slf4j
    public class CircleBreakerController {
    
        public static final String SERVICE_URL = "http://nacos-payment-provider";
    
        @Resource
        private RestTemplate restTemplate;
        //======= OpenFeign
        @Resource
        private PaymentServiceFeign paymentServiceFeign;
    
        @RequestMapping("/consumer/fallback/{id}")
    //    @SentinelResource(value = "fallback")         //没有任何配置
    //    @SentinelResource(value = "fallback",fallback ="handlerFallback")  //fallback只负责业务异常
        @SentinelResource(value = "fallback", fallback = "handlerFallback", 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("IllegalArgument ,非法参数异常...");
            } else if (result.getData() == null) {
                throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
            }
    
            return result;
        }
    
        public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
            Payment payment = new Payment(id, "null");
            return new CommonResult(444, "异常handlerFallback,exception内容: " + e.getMessage(), payment);
        }
    
        public CommonResult blockHandler(@PathVariable Long id, BlockException e) {
            Payment payment = new Payment(id, "null");
            return new CommonResult(444, "blockHandler-sentinel 限流,BlockException: " + e.getMessage(), payment);
        }
    }
    
    1. 消费端的RestTemplate(远程调用)配置负载均衡
    @Configuration
    public class ApplicationContextConfig {
    
        @Bean
        @LoadBalanced
        public RestTemplate getRestTemplate() {
            return new RestTemplate();
        }
    }
    
    

    1.3 测试

    1.3.1没有任何配置

    http://localhost:84/consumer/fallback/4
    前提没有限流和降级处理 出现异常直接返回Errorpage

    在这里插入图片描述

    1.3.2只配置fallback

    处理业务中的异常

        @RequestMapping("/consumer/fallback/{id}")
        @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("IllegalArgument ,非法参数异常...");
            } else if (result.getData() == null) {
                throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
            }
    	}
    	 public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
            Payment payment = new Payment(id, "null");
            return new CommonResult(444, "异常handlerFallback,exception内容: " + e.getMessage(), payment);
        }
    

    访问http://localhost:84/consumer/fallback/4 一定会出现异常
    并没有返回异常页面 而是调用handlerFallback方法

    在这里插入图片描述

    SentinelResource的·fallback·:针对于方法级别的处理 注意:方法的返回值请求参数对应 并且添加一个异常方法Throwable e
    springmvc:全局异常异常处理:针对于异常类型进行处理
    配置fallback出现异常走指定的fallback方法 控制台不会进行打印异常

    1.3.3只配置blockHandler

    @RequestMapping("/consumer/fallback/{id}")
        @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("IllegalArgument ,非法参数异常...");
            } else if (result.getData() == null) {
                throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
            }
            return result;
        }
        public CommonResult blockHandler(@PathVariable Long id, BlockException e) {
        	Payment payment = new Payment(id, "null");
        	return new CommonResult(444, "blockHandler-sentinel 限流,BlockException: " + e.getMessage(), payment);
        }
    

    在这里插入图片描述

    访问localhost:84/consumer/fallback/4 一定会抛出异常

    第一次访问 在这里插入图片描述

    第二次 访问 和第一次一样

    第三次访问
    已经进行熔断了

    在这里插入图片描述

    1.3.4 fallback和blockHandler都配置

    在这里插入图片描述

    在这里插入图片描述

    前两次使用fallback
    两次异常触发了降级 使用blockHandler方法

    1.3.5 结论

    fallback:只负责业务异常
    blockHandle:只负责Sentinel控制台配置违规 使用该属性只是替换默认的违规提示
    参考博文:你知道Sentinel限流、降级的统一处理吗?

    2. Feign系列

    pom

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    

    yml

    
    #对Feign的支持
    feign:
      sentinel:
        enabled: true
    
    //远程调用service
    //fallback 熔断调用的类
    @FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
    public interface PaymentService
    {
        @GetMapping(value = "/paymentSQL/{id}")
        public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
    }
     
    //熔断实现类
    @Component
    public class PaymentFallbackService implements PaymentService
    {
        @Override
        public CommonResult<Payment> paymentSQL(Long id)
        {
            return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
        }
    }
    

    在这里插入图片描述

    二、熔断框架对比

    同类组件功能对比

    SentinelHystrixresilience4j
    隔离策略信号量隔离(并发控制)线程池隔离/信号量隔离信号量隔离
    熔断降级策略基于慢调用比例、异常比例、异常数基于异常比例基于异常比例、响应时间
    实时统计实现滑动窗口(LeapArray)滑动窗口(基于 RxJava)Ring Bit Buffer
    动态规则配置支持近十种动态数据源支持多种数据源有限支持
    扩展性多个扩展点插件的形式接口的形式
    基于注解的支持支持支持支持
    单机限流基于 QPS,支持基于调用关系的限流有限的支持Rate Limiter
    集群流控支持不支持不支持
    流量整形支持预热模式与匀速排队控制效果不支持简单的 Rate Limiter 模式
    系统自适应保护支持不支持不支持
    热点识别/防护支持不支持不支持
    多语言支持Java/Go/C++JavaJava
    Service Mesh 支持支持 Envoy/Istio不支持不支持
    控制台提供开箱即用的控制台,可配置规则、实时监控、机器发现等简单的监控查看不提供控制台,可对接其它监控系统

    在这里插入图片描述

    三、持久化

    maven配置

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

    yml配置

    spring:
      application:
        name: cloudalibaba-sentinal-service
      cloud:
        nacos:
          discovery:
            #Nacos服务注册中心地址
            server-addr: localhost:8848
        sentinel:
          transport:
            #配置Sentin dashboard地址
            dashboard: localhost:8080
            port: 8719        # 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口
          datasource: #持久化配置
            ds1:  
              nacos:
                server-addr: localhost:8848
                dataId: cloudalibaba-sentinel-service
                groupId: DEFAULT_GROUP
                data-type: json
                rule-type: flow
    

    nacos中
    在这里插入图片描述

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

    在这里插入图片描述
    启动8401后刷新sentinel发现业务规则有了
    在这里插入图片描述
    在这里插入图片描述

    结论:
    会把nacos中配置的同步到sentinel 注意在sentinel界面中配置的不会添加到nacos中

  • 相关阅读:
    【Delphi】MD5算法(二):应用
    迅雷不能下载FlashPlayer,下载后自动删除,狂汗!!!
    工作笔记1
    GridControl 获取筛选后的数据{笔记}
    Invoke与BeginInvoke[转]
    这几项能力不知道要几年
    你永远不要去做的事1【译】
    window环境变量——心得【转】
    刚做好的网站客服系统,欢迎大家测试
    .Net 2.0里有一个有用的新功能:迭代器
  • 原文地址:https://www.cnblogs.com/idcode/p/14551365.html
Copyright © 2020-2023  润新知