赞
踩
一、添加依赖
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
- </dependency>
二、配置文件配置地址
- spring:
- cloud:
- sentinel:
- transport:
- dashboard: localhost:8080
三、流控模式介绍
直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
关联:统计与当前资源相关的另一个资源触发阈值时,对当前资源限流
使用场景:比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是有限支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。
链路:统计从指定链路访问到本资源的请求触发阈值时,对指定链路限流
例如有两条请求链路:
如果只希望统计从/test2进入到/common的请求,则可以这样配置:
注意:
1、Sentinel默认会将Controller方法做context整合,导致链路模式的流控失效,需要修改application.yml,添加配置:
spring:
cloud:
sentinel:
web-context-unify: false # 关闭context整合
2、Sentinel默认只标记Controller中的方法为资源,如果要标记其它方法(如service方法),需要利用@SentinelResource注解,示例:
@SentinelResource("goods")
public void queryGoods() {
System.err.println("查询商品");
}
四、流控效果
快速失败:QPS超过阈值时,拒绝新的请求。
warm up: QPS超过阈值时,拒绝新的请求;但QPS阈值是逐渐提升的,可以避免冷启动时高并发导致服务宕机。
排队等待:请求会进入队列,按照阈值允许的时间间隔依次执行请求;如果请求预期等待时长大于超时时间,直接拒绝。
五、热点参数限流
热点参数限流是分别统计参数值相同的请求,判断是否超过QPS阈值。并且可以对部分参数设置例外配置:
注意:热点参数限流对默认的SpringMVC资源无效,必须手动添加@SentinelResource注解
六、FeignClient整合Sentinel
Sentinel支持的雪崩解决方案:1、线程隔离(仓壁模式)2、降级熔断
(1)在application.yml中配置:feign.sentienl.enable=true
feign:
sentinel:
enabled: true # 开启Feign的Sentinel功能
(2)给FeignClient编写FallbackFactory并注册为Bean
- public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
- @Override
- public UserClient create(Throwable throwable) {
- // 创建UserClient接口实现类,实现其中的方法,编写失败降级的处理逻辑
- return new UserClient() {
- @Override
- public User findById(Long id) {
- // 记录异常信息
- log.error("查询用户失败", throwable);
- // 根据业务需求返回默认的数据,这里是空用户
- return new User();
- }
- };
- }
- }
-
- @Bean
- public UserClientFallbackFactory userClientFallback(){
- return new UserClientFallbackFactory();
- }

(3)将FallbackFactory配置到FeignClient
- @FeignClient(value = "userservice", fallbackFactory =UserClientFallbackFactory.class)
- public interface UserClient {
- @GetMapping("/user/{id}")
- User findById(@PathVariable("id") Long id);
- }
七、熔断降级策略
1、慢调用比例:超过指定时长的调用为慢调用,统计单位时长内慢调用的比例,超过阈值则熔断
2、异常比例:统计单位时长内异常调用的比例,超过阈值则熔断
3、异常数:统计单位时长内异常调用的次数,超过阈值则熔断
八、授权规则
授权规则可以对调用方的来源做控制,有白名单和黑名单两种方式。
Sentinel是通过RequestOriginParser这个接口的parseOrigin来获取请求的来源的。
- public interface RequestOriginParser {
- /**
- * 从请求request对象中获取origin,获取方式自定义
- */
- String parseOrigin(HttpServletRequest request);
- }
所以在填写流控应用的时候,是根据自定义的RequestOriginParser来填写(比如在请求header上添加值来区分是网关过来的请求还是直接访问的服务的请求)
- @Component
- public class HeaderOriginParser implements RequestOriginParser {
- @Override
- public String parseOrigin(HttpServletRequest request) {
- String origin = request.getHeader("origin");
- if(StringUtils.isEmpty(origin)){
- return "blank";
- }
- return origin;
- }
- }
九、自定义返回方法
只需实现BlockExceptionHandler接口即可
- @Component
- public class SentinelBlockHandler implements BlockExceptionHandler {
- @Override
- public void handle(
- HttpServletRequest httpServletRequest,
- HttpServletResponse httpServletResponse, BlockException e) throws Exception {
- String msg = "未知异常";
- int status = 429;
- if (e instanceof FlowException) {
- msg = "请求被限流了!";
- } else if (e instanceof DegradeException) {
- msg = "请求被降级了!";
- } else if (e instanceof ParamFlowException) {
- msg = "热点参数限流!";
- } else if (e instanceof AuthorityException) {
- msg = "请求没有权限!";
- status = 401;
- }
- httpServletResponse.setContentType("application/json;charset=utf-8");
- httpServletResponse.setStatus(status);
- httpServletResponse.getWriter().println("{\"message\": \"" + msg + "\", \"status\": " + status + "}");
- }
- }

十、配置规则持久化三种模式
1、原始模式:保存在内存
2、pull模式:保存在本地文件或数据库,定时去读取
3、push模式:保存在nacos,监听变更实时更新
通常生产环境采用push模式,需要修改Sentinel-dashboard的源码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。