Sentinel 的降级功能
SpringCloud Alibaba Sentinel 对降级功能的支持
@SentinelResource
中fallback
、fallbackClass
指定异常降级的类和方法Sentinel
还对Feign
实现了适配,支持Feign的容错降级
-
编写
bootstrap.yml
# 打开 Sentinel 对 Feign 的支持 feign: sentinel: enabled: true
-
编写
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
的支持
-
编写
bootstrap.yml
文件# 打开 Sentinel 对 Feign 的支持 feign: sentinel: enabled: true
-
编写实例代码
/** * @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:集群效果
-
在
pom.xml
添加依赖<!-- Sentinel 使用 Nacos 存储规则 --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
-
按照限流规则的定义添加
/** * 在 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"); }
-
在
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
评论区