接口限流
接口限流
Sentinel
由阿里巴巴中间件团队开发的开源项目,是一种面向分布式微服务架构的轻量级高可用流量控制组件
提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性

sentinel分为两部分:
- sentinel-dashboard(控制面板):提供实时监控之外,还提供了流控规则、熔断规则的在线维护等功能
- 客户端整合:每个微服务客户端都需要整合sentinel的客户端封装与配置,才能将监控信息上报给dashboard展示以及实时的更改限流或熔断规则等。
部署
部署Sentinel Dashboard
下载地址:sentinel-dashboard
- 运行jar包 - 1 
 2
 3
 4
 5
 6- java -jar sentinel-dashboard-1.8.3.jar
 #后面可跟参数
 -Dserver.port=8080 #设置端口,默认8080
 -Dsentinel.dashboard.auth.username=sentinel #设置用户名, 默认sentinel
 -Dsentinel.dashboard.auth.password=123456 #设置密码, 默认sentinel
- 访问 - localhost:8080来打开控制面板
客户端整合Sentinel
- 导入依赖 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10- <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <!--sentinel-->
 <dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
 <version>2.1.1.RELEASE</version>
 </dependency>
- 配置Sentinel Dashboard的访问地址 - 1 
 2
 3
 4
 5
 6
 7
 8
 9- spring:
 cloud:
 sentinel:
 transport:
 dashboard: localhost:8080 # 控制面板端口
 application:
 name: alibaba-sentinel-rate-limiting # 服务名
 server:
 port: 8001 # 服务端口
- 编写一个访问的接口 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11- package com.xw.controller;
 @Slf4j
 @RestController
 public class TestController {
 @GetMapping("/hello")
 public String hello() {
 return "hello";
 }
 }
- 访问此接口和控制台   
限流
配置限流规则
对访问某个接口的所有请求进行限流


流控模式:
- 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认模式。 
- 关联:统计与当前相关的另一个资源,触发阈值时,对当前资源限流。 
- 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流 - 链路模式中,是对不同来源的两个链路做监控。但是sentinel默认会给进入SpringMVC的所有请求设置同一个root资源,会导致链路模式失效。 - 我们需要关闭这种对SpringMVC的资源聚合 - 1 
 2
 3
 4- spring:
 cloud:
 sentinel:
 web-context-unify: false # 关闭context整合
流控效果:
- 快速失效:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。
- warm up:预热模式,对超出阈值的请求同样是拒绝,并抛出异常。但这种模式阈值会动态变化,从一个较小的值逐渐增加到最大值。
- 排队等待:让所有请求按照先后次序排队执行,两个请求的间隔不能小于指定时长。对流量进行整形,将波动的qps整形成平滑的直线。
配置热点参数限流
粒度更细,对访问某个接口的指定参数进行限流
- 热点参数限流对默认的SpringMVC是无效的,添加@SentinelResource注解开启热点限流 - 1 
 2
 3
 4
 5
 6- @SentinelResource("hot") //设置资源名
 @GetMapping("/hot")
 public String hot(@RequestParam String id) {
 System.out.println("热点参数");
 return "success";
 }
- 通过控制面板设置   
隔离
对访问某个接口的线程进行限制
FeignClient整合Sentinel
将Feign与Sentinel整合,在Feign里面实现线程隔离和服务熔断。
SpringCloud版本为<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
循环依赖可能是版本问题
Feign整合Sentinel的步骤:
- 在application.yml中配置:feign.sentienl.enable=true
- 给FeignClient编写FallbackFactory并注册为Bean
- 将FallbackFactory配置到FeignClient
- 在用到feign的类的配置中开启sentinel功能 - 1 
 2
 3- feign:
 sentinel:
 enabled: true # 开启feign对sentinel的支持
- 编写失败降级逻辑 - 业务失败后,不能直接报错,而应该返回用户一个友好提示或者默认结果,这个就是失败降级逻辑。 - 给FeignClient编写失败后的降级逻辑 - ①方式一:FallbackClass,无法对远程调用的异常做处理 - ②方式二:FallbackFactory,可以对远程调用的异常做处理 - 在feign-api包中 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16- package cn.itcast.client.fallback;
 @Slf4j
 public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
 @Override
 public UserClient create(Throwable throwable) {
 return new UserClient() {
 @Override
 public User findById(Long id) {
 log.error("查询用户异常");
 return new User();
 }
 };
 }
 }
- 将UserClientFallbackFactory注册为一个bean - 1 
 2
 3
 4
 5
 6
 7- public class DefaultFeignConfiguration {
 @Bean
 public UserClientFallbackFactory userClientFallbackFactory() {
 return new UserClientFallbackFactory();
 }
 }
- 在用到feign的类上记得在启动类上设置默认配置类 - 1 - @EnableFeignClients(clients = {UserClient.class},defaultConfiguration = DefaultFeignConfiguration.class)
- 在feing-api项目中的UserClient接口中使用UserClientFallbackFactory - 1 
 2
 3
 4
 5
 6
 7
 8- package cn.itcast.client;
 //注意是fallbackFactory不是fallback
 @FeignClient(value = "userservice", fallbackFactory = UserClientFallbackFactory.class)
 public interface UserClient {
 @GetMapping("/user/{id}")
 User findById(@PathVariable("id") Long id);
 }
- 重启服务 
线程隔离
线程隔离的两种手段
- 信号量隔离 
- 线程池隔离 
信号量隔离的特点
- 基于计数器模式,简单,开销小,适合高扇出的场景
线程池隔离的特点
- 基于线程池模式,有额外开销,但隔离控制更强
配置隔离规则


熔断
熔断降级是解决雪崩问题的重要手段。其思路是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求;而当服务恢复时,断路器会放行访问该服务的请求。
熔断策略:
- 慢调用:当响应时间大于设定的值(RT)时,为一次慢调用。若慢调用的次数大于设定的阈值,请求数量超过设定的最小数量,则会触发熔断
- 异常比例:单位时间里出现异常的比例大于设置的比例,则会触发熔断
- 异常数: 单位时间里出现异常的比例大于设置的数值,则会触发熔断
配置慢调用


配置异常比例/异常数

授权
授权规则可以对调用方的来源做控制,有白名单和黑名单两种方式。
只对有授权的请求提供服务
默认情况下,sentinel对一切请求的来源都被认为是一样的值default。
- 自定义请求来源解析器 - 配置授权规则时会根据解析器的返回值来判断请求来源 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19- package cn.itcast.order.sentinel;
 /**
 * 自定义来源解析器
 */
 @Component
 public class HeaderOriginParser implements RequestOriginParser {
 @Override
 public String parseOrigin(HttpServletRequest request) {
 //从请求头获取来源信息
 String origin = request.getHeader("origin");
 //请求头中没有"origin",则默认值为"blank"
 if (StringUtil.isEmpty(origin)) {
 origin = "blank";
 }
 return origin;
 }
 }
- 通过配置,给网关添加过滤器 - 通过网关的请求都会被加上origin的请求头,值为”gateway” - 1 
 2
 3
 4
 5- spring:
 cloud:
 gateway:
 default-filters:
 - AddRequestHeader=origin,gateway
- 配置授权规则   
自定义异常结果
发生限流、降级、授权拦截时,都会抛出异常到调用方,异常结果都是flow limmiting(限流)
异常种类
| 异常 | 说明 | 
|---|---|
| FlowException | 限流异常 | 
| ParamFlowException | 热点参数限流的异常 | 
| DegradeException | 降级异常 | 
| AuthorityException | 授权规则异常 | 
| SystemBlockException | 系统规则异常 | 
通过自定义堵塞异常处理器来自定义返回结果
| 1 |  |