• [Spring-Cloud-Alibaba] Sentinel 整合RestTemplate & Feign


    Sentinel API

    Github : WIKI

    • Sphu (指明要保护的资源名称)
    • Tracer (指明调用来源,异常统计接口)
    • ContextUtil(标示进入调用链入口)
    • 流控规则(针对来源属性)
      @GetMapping("/test-sentinel-api")
          public String testSentinelAPI(@RequestParam(required = false) String a) {
              String resourceName = "test-sentinel-api";
              
              ContextUtil.enter(resourceName, "user-center-service");
              // 定义一个sentinel 保护的资源,名称是test-sentinel-api
              Entry entry = null;
              try {
      
                  entry = SphU.entry(resourceName);
                  // ...被保护的业务逻辑处理
                  if (StringUtils.isEmpty(a)) {
                      // Sentinel 默认只会统计BlockException & BlockException的子类,如果想统计其他异常信息,添加Tracer
                      throw new IllegalArgumentException("A is not empty.");
                  }
                  return a;
                  // block Exception: 如果被保护的资源被限流或者降级了,就会抛异常出去
              } catch (BlockException e) {
                  log.error("我被限流啦!!{}", e);
                  return "我被限流啦!!";
              } catch (IllegalArgumentException argEx) {
                  // 统计当前异常发生次数 / 占比
                  Tracer.trace(argEx);
                  return "非法参数信息";
              } finally {
                  if (entry != null) {
                      entry.exit();
                  }
                  ContextUtil.exit();
              }
          }
    
    • 降级规则
      @GetMapping("/test-sentinel-api")
          public String testSentinelAPI(@RequestParam(required = false) String a) {
      
              // 定义一个sentinel 保护的资源,名称是test-sentinel-api
              Entry entry = null;
              try {
                  entry = SphU.entry("test-sentinel-api");
                  // ...被保护的业务逻辑处理
                  if (StringUtils.isEmpty(a)) {
                      // Sentinel 默认只会统计BlockException & BlockException的子类,如果想统计其他异常信息,添加Tracer
                      throw new IllegalArgumentException("A is not empty.");
                  }
                  return a;
                  // block Exception: 如果被保护的资源被限流或者降级了,就会抛异常出去
              } catch (BlockException e) {
                  log.error("我被限流啦!!{}", e);
                  return "我被限流啦!!";
              } catch (IllegalArgumentException argEx) {
                  // 统计当前异常发生次数 / 占比
                  Tracer.trace(argEx);
                  return "非法参数信息";
              } finally {
                  if (entry != null) {
                      entry.exit();
                  }
              }
      
          }
    

    Sentinel Annotation

    源码:com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect & com.alibaba.csp.sentinel.annotation.aspectj.AbstractSentinelAspectSupport

    • SentinelResource 使用该注解重构上述方法
          @GetMapping("/test-sentinel-resource")
          @SentinelResource(value = "test-sentinel-api", blockHandler = "blockException", fallback = "fallback")
          public String testSentinelResource(@RequestParam(required = false) String a) {
              // ...被保护的业务逻辑处理
              if (StringUtils.isEmpty(a)) {
                  // Sentinel 默认只会统计BlockException & BlockException的子类,如果想统计其他异常信息,添加Tracer
                  throw new IllegalArgumentException("A is not empty.");
              }
              return a;
          }
      
          /**
           * testSentinelResource BlockException method
           */
          public String blockException(String a, BlockException e) {
              log.error("限流了,{}", e);
              return "blockHandler 对应《限流规则》";
          }
      
          /**
           * testSentinelResource fallback method
           * {@link SentinelResource} #fallback 在< 1.6的版本中,不能补货BlockException
           */
          public String fallback(String a) {
              return "fallback 对应《降级规则》";
          }
    

    RestTemplate 整合Sentinel

    使用 @SentinelRestTemplate.

    resttemplate.sentinel.enabled可以开关是否启用该注解。(开发阶段很有意义。)

    源码:com.springframework.cloud.alibaba.sentinel.custom.SentinelBeanPostProcessor

    @Bean
    @LoadBalanced
    @SentinelRestTemplate
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    @Autowired
    private RestTemplate restTemplate;
    ...
    

    Feign整合 Sentinel

    配置文件中添加 feign.sentinel.enabled: true来开启

    1. 编写fallback 类,实现feign client
       @Component
       public class UserCenterFeignClientFallback implements IUserCenterFeignClient {
           @Override
           public UserDTO findById(Long userId) {
               UserDTO userDTO = new UserDTO();
               userDTO.setWxNickname("默认用户");
               return userDTO;
           }
       }
       
       @Slf4j
       @Component
       public class UserCenterFeignClientFallbackFactory implements FallbackFactory<IUserCenterFeignClient> {
       
           @Override
           public IUserCenterFeignClient create(Throwable cause) {
               return new IUserCenterFeignClient() {
                   @Override
                   public UserDTO findById(Long userId) {
                       log.warn("远程调用被限流/降级,{}", cause);
                       UserDTO userDTO = new UserDTO();
                       userDTO.setWxNickname("默认用户");
                       return userDTO;
                   }
               };
           }
       }
    
    1. 应用fallback class
       /**
        * IUserCenterFeignClient for 定义 user-center feign client
        * fallbackFactory 可以拿到异常信息
        * fallback 无法拿到异常信息
        *
        * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
        * @since 2019/7/15
        */
       @FeignClient(name = "user-center",
               // fallback = UserCenterFeignClientFallback.class,
               fallbackFactory = UserCenterFeignClientFallbackFactory.class
       )
       public interface IUserCenterFeignClient {
           @GetMapping(path = "/users/{userId}")
           public UserDTO findById(@PathVariable Long userId);
       }
       
       
    
    1. 启动应用,设置流控规则,结果展示如下
       {
           id: 1,
           ...
           wxNickName: "默认用户"
       }
    

    源码:org.springframework.cloud.alibaba.sentinel.feign.SentinelFeign

  • 相关阅读:
    让Dreamweaver支持cshtml (MVC Razor环境)
    href="#"与href="javascript:void(0)"的区别
    ASP.NET MVC 4 中Razor 视图中JS无法调试 (重要)
    03011_HttpServletRequest
    1004. 成绩排名 (20)
    1003. 我要通过!(20)
    C语言文件读写命令fprintf和fscanf
    1002. 写出这个数 (20)
    1001. 害死人不偿命的(3n+1)猜想 (15)
    汇编in和out实例解析
  • 原文地址:https://www.cnblogs.com/zhangpan1244/p/11216292.html
Copyright © 2020-2023  润新知