侧边栏壁纸
博主头像
qingtian博主等级

喜欢是一件细水流长的事,是永不疲惫的双向奔赴~!

  • 累计撰写 104 篇文章
  • 累计创建 48 个标签
  • 累计收到 1 条评论

使用 Sentinel 对服务间调用

qingtian
2022-07-31 / 0 评论 / 0 点赞 / 586 阅读 / 5,502 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-08-08,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Sentinel 的降级功能

SpringCloud Alibaba Sentinel 对降级功能的支持

  • @SentinelResourcefallbackfallbackClass 指定异常降级的类和方法
  • Sentinel 还对Feign 实现了适配,支持Feign的容错降级
  1. 编写bootstrap.yml

    # 打开 Sentinel 对 Feign 的支持
    feign:
      sentinel:
        enabled: true
    
  2. 编写 fallback兜底类

    /**
     * @author Guank
     * @version 1.0
     * @description: sentinel 回退降级的兜底策略
     * @date 2022-07-24 17:43
     */
    @Slf4j
    public class GuankFallbackHandler {
    
        /**
         * getJwtTokenFromAuthorityCenter 的外部调用兜底策略
         * @param usernameAndPassword
         * @return
         */
        public static JwtToken getTokenFromAuthorityServiceFallback(UsernameAndPassword usernameAndPassword) {
            log.error("get token from authority service fallback : [{}]", JSON.toJSONString(usernameAndPassword));
            return new JwtToken("imooc-guank-fallback");
        }
    
        public static JwtToken ignoreExceptionFallback(Integer code) {
            log.error("ignore exception input code is : [{}] has trigger exception",code);
            return new JwtToken("imooc-guan-fallback");
        }
    }
    
    -----------------------------------------------------------------------------------------------------
    // 使用兜底类对异常进行处理
    /**
         * 注入没有被 sentinel 增强的 restTemplate
         */
        @Autowired
        private RestTemplate restTemplate;
    
        @PostMapping("/get-token")
        @SentinelResource(value = "getJwtTokenFromAuthorityCenter",
                fallback = "getTokenFromAuthorityServiceFallback", fallbackClass = GuankFallbackHandler.class)
        public JwtToken getJwtTokenFromAuthorityCenter(@RequestBody UsernameAndPassword usernameAndPassword) {
            String requestUrl = "http://127.0.0.1:7000/ecommerce-authority-center/authority/token";
            log.info("RestTemplate from authority center url and body : [{}] , [{}]"
                    ,requestUrl, JSON.toJSONString(usernameAndPassword));
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
            return restTemplate.postForObject(requestUrl,
                    new HttpEntity<>(JSON.toJSONString(usernameAndPassword),httpHeaders),
                    JwtToken.class);
        }
    

某些情况需要让出现的异常抛向方法的调用者,不用 Sentinel 进行兜底处理

public static JwtToken ignoreExceptionFallback(Integer code) {
        log.error("ignore exception input code is : [{}] has trigger exception",code);
        return new JwtToken("imooc-guan-fallback");
    }

--------------------------------------------------------------------------------------------------------
/**
     * 让 Sentinel 忽略一些异常
     * @param code
     * @return
     */
    @GetMapping("/ignore-exception")
    @SentinelResource(value = "ignoreException",
                    fallback = "ignoreExceptionFallback",
                    fallbackClass = GuankFallbackHandler.class,
                    exceptionsToIgnore = {NullPointerException.class})
    public JwtToken ignoreException(@RequestParam Integer code) {
        if (code % 2 == 0) {
            throw new NullPointerException("you input code is : " + code);
        }
        return new JwtToken("imooc-guank-fallback");
    }

Sentinel 对 openFeign的支持

  1. 编写 bootstrap.yml文件

    # 打开 Sentinel 对 Feign 的支持
    feign:
      sentinel:
        enabled: true
    
  2. 编写实例代码

    /**
     * @author Guank
     * @version 1.0
     * @description: 通过 Sentinel 对 openFeign 实现熔断降级
     * @date 2022-07-30 16:15
     */
    @FeignClient(
            value = "e-commrece-imooc",
            fallback = SentinelFeignClientFallback.class
    )
    public interface SentinelFeignClient {
    
        @RequestMapping(value = "guank",method = RequestMethod.GET)
        CommonResponse<String> getResultByFeign(@RequestParam Integer code);
    }
    
    --------------------------------------------------------------------------------------------------------
    @Slf4j
    @Component
    public class SentinelFeignClientFallback implements SentinelFeignClient {
    
        @Override
        public CommonResponse<String> getResultByFeign(Integer code) {
            log.error("request supply for test has some error : [{}]",code);
            return new CommonResponse<>(
                    -1,
                    "sentinel feign fallback",
                    "input code is :" + code
            );
        }
    }
    
    -------------------------------------------------------------------------------------------------------
    /**
     * @author Guank
     * @version 1.0
     * @description: openfeign 集成 Sentinel 实现熔断降级
     * @date 2022-07-30 19:12
     */
    @RestController
    @Slf4j
    @RequestMapping("/sentinel-feign")
    public class SentinelFeignController {
    
        @Autowired
        private SentinelFeignClient sentinelFeignClient;
    
        /**
         * 通过 feign 接口获取结果
         * @param code
         * @return
         */
        @GetMapping("/result-by-feign")
        public CommonResponse<String> getResultByFeign(@RequestParam Integer code) {
            log.info("coming in get result by fiegn : [{}]",code);
            return sentinelFeignClient.getResultByFeign(code);
        }
    }
    
    

Sentinel 结合 Nacos 实现限流规则持久化

  • Sentinel Dashboard将规则保存在内存中,重启后就会丢失,所以,考虑使用外部持久化方案
  • 在 Nacos 中创建规则,Nacos 会推送到客户端
  • Sentinel Dashboard 也会从 Nacos 去获取配置信息

SpringCloud alibaba Sentinel 配置信息

  • Sentinel 存储在 Nacos 中的限流数据结构

    • resource:资源名
    • limitApp:调用来源 如果为 default则不区分调用来源
    • grade:阈值类型 1 QPS 0 并发线程数
    • count:限流的阈值
    • strategy:流控模式 :0 直接 1 关联 2 链路
    • controlBehavior:流控效果 0 快速失败 1 Warm Up ---让通过的流量缓慢增加 在一定时间内增加到阈值上限 2 排队等待
    • clusterMode:集群效果
  1. pom.xml添加依赖

    <!-- Sentinel 使用 Nacos 存储规则 -->
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-datasource-nacos</artifactId>
            </dependency>
    
  2. 按照限流规则的定义添加

    /**
         * 在 dashboard 中新增流控规则 根据资源名称新增流控规则
         * @return
         */
        @GetMapping("/by-resource")
        @SentinelResource(value = "byResource",blockHandler = "guankHandlerBlockException", blockHandlerClass = GuankBlockHandler.class)
        public CommonResponse<String> byResource() {
            log.info("coming in rate limit controller by resource");
            return new CommonResponse<>(0,"by resource");
        }
    
  3. bootstrap.yml中配置数据源

    sentinel:
          # 配置 sentinel dashboard 地址
          transport:
            dashboard: 192.168.0.103:7777
            port: 8719 # 会在应用对应的机器上启动一个 Http Server, 该 Server 会与 Sentinel 控制台做交互
          datasource:
            # 名称任意, 代表数据源
            ds:
              nacos:
                # NacosDataSourceProperties.java 中定义
                server-addr: ${spring.cloud.nacos.discovery.server-addr}
                dataId: ${spring.application.name}-sentinel
                namespace: ${spring.cloud.nacos.discovery.namespace}
                groupId: DEFAULT_GROUP
                data-type: json
                # 规则类型: com.alibaba.cloud.sentinel.datasource.RuleType
                # FlowRule 就是限流规则
                rule-type: flow
          # 服务启动直接建立心跳连接
          eager: true
    
0

评论区