冲
Sentinel基本概念
资源:只要通过Sentinel API定义的代码,就是资源,能够被Sentinel保护起来。大部分情况,可以使用方法签名,URL,服务名称作为资源名来标示资源。
规则:包括流量控制规则、熔断降级规则、系统保护规则。所有规则可以用动态实行调整。
Sentinel工作主流程
Spring Cloud Alibaba整合Sentinel
引入依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
配置yml
server:port: 8800spring:application:name: mall-user-sentinel-democloud:nacos:discovery:server-addr: 139.198.123.65:8848sentinel:transport:# 添加sentinel控制台dashboard: localhosts:8080# 指定应用于sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer# port: 8719
Sentinel控制台
运行 sentinel-dashboard jar 包
流控规则

- 资源名:api接口
- 针对来源:默认default,当多个微服务都调用这个资源时,可以对配置微服务名来对指定的微服务设置阈值
阈值类型:QPS与线程数 如:单机阈值为10
- QPS:每秒访问资源次数>10进行限流
-
直接
关联
如果关联资源超出阈值,则当前资源会被限流。
/user/info/{id}访问的QPS超过2,则/user/findOrderbByUserId/{id}会被限流,/user/info/{id}不会被限流。
链路
屌代码有bug。
<!--- 解决流控链路不生效的问题--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-web-servlet</artifactId></dependency>
@Configurationpublic class SentinelConfig {@Beanpublic FilterRegistrationBean sentinelFilterRegistration() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new CommonFilter());registration.addUrlPatterns("/*");// 入口资源关闭聚合 解决流控链路不生效的问题registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");registration.setName("sentinelFilter");registration.setOrder(1);return registration;}}
继续报错

public class SentinelConfig { @Bean public FilterRegistrationBean sentinelFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new CommonFilter()); registration.addUrlPatterns("/*"); // 入口资源关闭聚合 解决流控链路不生效的问题 registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false"); registration.setName("sentinelFilter"); registration.setOrder(1); //CommonFilter的BlockException自定义处理逻辑 WebCallbackManager.setUrlBlockHandler(new MyUrlBlockHandler()); return registration; } }@Slf4j public class MyUrlBlockHandler implements UrlBlockHandler { @Override public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException e) throws IOException { log.info("UrlBlockHandler BlockException================" + e.getRule()); R r = null; if (e instanceof FlowException) { r = R.error(100, "接口限流了"); } else if (e instanceof DegradeException) { r = R.error(101, "服务降级了"); } else if (e instanceof ParamFlowException) { r = R.error(102, "热点参数限流了"); } else if (e instanceof SystemBlockException) { r = R.error(103, "触发系统保护规则了"); } else if (e instanceof AuthorityException) { r = R.error(104, "授权规则不通过"); } //返回json数据 response.setStatus(500); response.setCharacterEncoding("utf-8"); response.setContentType(MediaType.APPLICATION_JSON_VALUE); new ObjectMapper().writeValue(response.getWriter(), r); } }@Override @SentinelResource(value = "getUser", blockHandler = "handleException") public OrderEntity getUser(Integer id) { OrderEntity user = baseMapper.selectById(id); return user; } public OrderEntity handleException(int id, BlockException ex) { OrderEntity userEntity = new OrderEntity(); userEntity.setUserId("===被限流降级啦==="); return userEntity; }如果入口资源访问getUser超过了阈值,则会被限流。免费版的这个功能有bug,不建议用。
流控效果
快速失败
当QPS超过任意规则的阈值后,新请求会被拒绝,抛出FolwException
Warm Up
给定冷系统预热时间,避免冷系统被压垮。冷加载因子,codeFactor默认是3,请求从threshold/3开始,经过预热时长,逐渐升至设置的QPS

前5秒,每秒访问3次,后面慢慢递增到10次。排队等待
会严格控制请求的间隔时间。

每秒通过10个请求, 请求超时500ms会被拒绝。降级规则
熔断策略
慢调用比例

最大RT为慢请求的ms数。
当慢请求的比例大于0.2,并且在单位时间内的请求大于5条,在接下来三秒将会熔断。异常比例

接口异常的比例超过0.4,并且单位时长的请求数超过5,将会在接下来的3秒对资源进行熔断。异常数

接口异常的数量超过5,并且单位时长的请求数超过5,将会在接下来的3秒对资源进行熔断。热点规则

该资源传参第一个值为1的阈值为2,其他阈值为3.
接口格式:@RequestMapping("/info/{id}") @SentinelResource(value = "userinfo", blockHandlerClass = CommonBlockHandler.class, blockHandler = "handleException2", fallbackClass = CommonFallback.class, fallback = "fallback") public R info(@PathVariable("id") Integer id) { OrderEntity user = orderService.getById(id); if (id == 4) { throw new IllegalArgumentException("异常参数"); } return R.ok().put("user", user); }系统规则
授权规则
@Component public class MyRequestOriginParser implements RequestOriginParser { /** * 通过request获取来源标识,交给授权规则进行匹配 * * @param request * @return */ @Override public String parseOrigin(HttpServletRequest request) { // 标识字段名称可以自定义 String origin = request.getParameter("serviceName"); // if (StringUtil.isBlank(origin)){ // throw new IllegalArgumentException("serviceName参数未指定"); // } return origin; } }@Bean public FilterRegistrationBean sentinelFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new CommonFilter()); registration.addUrlPatterns("/*"); // 入口资源关闭聚合 解决流控链路不生效的问题 registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false"); registration.setName("sentinelFilter"); registration.setOrder(1); //CommonFilter的BlockException自定义处理逻辑 WebCallbackManager.setUrlBlockHandler(new MyUrlBlockHandler()); //解决授权规则不生效的问题 //com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser WebCallbackManager.setRequestOriginParser(new MyRequestOriginParser()); return registration; }Sentinel整合OpenFeign
开启Sentinel对feign的支持
feign: sentinel: enabled: true
