第八章 微服务保护 v1.0
第一部分 微服务保护入门
一、雪崩问题及解决方案
1.雪崩问题
微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。
A服务在调用另一个已宕机服务B时,A服务久不释放连接导致资源耗尽,出现相互依赖的多级服务宕机的连锁反应
2.解决方案
- 超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待,能够一定程度上缓解雪崩问题
- 舱壁模式:也叫线程隔离,限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,但会有一定的资源浪费
- 熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求
- 流量控制:限制业务访问的QPS,避免服务由流量的突增而故障,能够有效预防雪崩(主要预防高并发流量导致的服务故障问题)
二、服务保护技术

三、Sentinel
1.简介
Sentinel是阿里巴巴开源的一款微服务流量控制组件,官网:Sentinel
2.安装
- 在Github下载对应jar包
- 拷贝到一个非中文的目录,运行:
java -jar sentinal-dashboard-1.8.1.jar - 访问网页,默认账号密码为sentinel
3.常用配置修改
在运行时直接添加:java -jar sentinal-dashboard-1.8.1.jar -D<配置项>=参数值
4.整合Sentinel
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-Cloud-starter-alibaba-sentinel</artifactId>
</dependency>spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080第二部分 Sentinel
一、流量控制
1.簇点链路
项目内的调用链路,链路中被监控的每一个接口都是一个资源
流控、熔断等都是针对簇点链路中的资源来设置的,可以通过Sentinel控制台来设置规则
2.流控模式
a.直接
(默认)统计当前资源的请求,触发阈值时对当前资源直接限流
b.关联
统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
使用场景:两个有竞争关系的资源;两个资源一个优先级较高,一个优先级较低
比如:用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是优先支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。
c.链路
统计从指定链路访问到本资源的请求,触发阈值时,对指定链路访问限流
使用场景:对某个特定的业务访问资源的请求进行限流
d.资源标记
Sentinel默认只标记Controller中的方法为资源进行监控,如果要标记其它方法,需要利用@SentinelResource注解
@SentinelResource("资源名")
public void queryName() {
//...
}Sentinel默认会将Controller方法做context整合,导致链路模式的流控失效,需要关闭该功能
//默认条件下controller1与controller2中的query资源会被视为同个资源
@GetMapping("controller1")
public String controller1() {
service.query(); //query被标记为资源
}
@GetMapping("controller2")
public String controller2() {
service.query(); //query被标记为资源
}spring:
cloud:
sentinel:
web-context-unify: false # 关闭context整合3.流控效果
a.快速失败
(默认)达到阈值后,新的请求会被立即拒绝并抛出FlowException异常
b.Warm up
预热模式,一般是应对服务冷启动的一种方案
预热模式会对超出阈值的请求同样拒绝并抛出异常,但阈值会动态变化,从一个较小值逐渐增加到最大阈值
相关指标:
- 单机阈值:最大QPS阈值(threshold)
- 预热时长:从初始QPS阈值到最大QPS阈值所需要的预热时间设置
- 冷启动因子(coldFactor):默认为3,一般不需要更改
- 初始QPS阈值:
threshold/coldFactor
c.排队等待
让请求按照顺序依次排队执行,且每两个请求的间隔不能小于指定时长,预期等待时间大于超时时间将直接拒绝
相关指标:
- 单机阈值:最大QPS阈值
- 超时时间:等待时间超过超时时间的请求将被拒绝并抛出异常
- 时间间隔:
1s/threshold
4.热点参数限流
常规限流统计访问某资源的所有请求;而热带参数限流统计参数值相同的请求,判断是否超过QPS阈值
相关指标:
- 参数索引:若参数为i,代表对第i+1个参数做统计
- 单机阈值:QPS阈值设定
- 统计窗口时长:统计计算单机阈值的时长
高级选项(参数例外项):
- 参数类型:需要修改流控规则的指定参数值的数值类型
- 参数值:需要修改流控规则的指定参数值的数值
- 限制阈值:对应请求限流的QPS阈值
注:热点参数限流只对使用@SentinelResource注解声明的资源生效
三、隔离与降级
1.FeignClient整合Sentinel
- 修改服务消费者配置
feign:
sentinel:
endabled: true # 开启Feign的Sentinel功能- 配置FeignClient失败后的降级逻辑
public class ClientFallbackFactory implements FallbackFactory<Client> {
@Override
public Client create(Throwable throwable) {
// 创建Client接口实现类,实现其中方法并编写降级逻辑
return new Client() {
@Override
public Response action() {
log.error("失败", throwable); // 日志记录
return new Response(); // 返回相应
}
}
}
}- 将ClientFallbackFactory注册为Bean
@Bean
public ClientFallbackFactory clientFallback() {
return new ClientFallbackFactory();
}- 在对应Client接口中使用ClientFallbackFactory
@FeignClient(value="service", fallbackFactory = ClientFallbackFactory.class)
public interface Client {
//...
}2.线程隔离
线程隔离默认有两种方式实现:线程池隔离、信号量隔离(Sentinel默认),只需要改变阈值类型即可切换
线程池隔离
优点:支持主动超时、支持异步调用
缺点:基于线程池模式,线程额外开销较大
使用场景:低扇出场景(相互依赖的服务较少)
信号量隔离
优点:基于计数器模式,轻量级、无额外开销
缺点:不支持主动超时、不支持异步调用
使用场景:高频率调用,高扇出场景(相互依赖的服务较多)
3.熔断降级
断路器统计服务调用的异常比例、慢请求比例,如果超出阈值会熔断该服务
断路器状态图

熔断策略
- 慢调用:指定时间内,若请求数量超过设定最小数量,慢调用比例大于设定阈值,则触发熔断
- 异常比例:指定时间内,如果调用此处超过指定请求数,且异常比例大于设定阈值,则触发熔断
- 异常数:指定时间内,如果调用此处超过指定请求数,且异常数大于设定阈值,则触发熔断
四、授权规则
对调用方的来源进行控制,有黑名单和白名单两种方式
Sentinel通过RequestOriginParser这个接口的parseOrigin来获取请求的来源的
@Component
public class HeaderOriginParser implements RequestOriginParser {
@0verride
public String parseOrigin(HttpServletRequest request) {
String origin = request.getHeader("origin");
if(StringUtils.isEmpty(origin)){
return "blank";
}
return origin;
}
}spring:
cloud:
gateway:
default-filters:
- AddRequestHeader=grigin,gateway #添加名为origin的请求头,值为gateway五、自定义异常结果
1.实现
要实现自定义异常结果,需要在服务提供者端定义类,实现BlockExceptionHandle接口

2.BlockException的子类

六、规则持久化
Sentinel默认会将流控规则保存在内存中,当重启时流控规则则会丢失,需要进行持久化
1.原始模式
Sentinel的默认模式,将规则保存在内存中,重启服务规则会丢失
2.pull模式
控制台将配置的规则推送到Sentinel客户端,客户端会将配置规则保存在本地文件或数据库中,服务会定时查询本地文件或数据库,更新本地规则

3.push模式
控制台将配置规则推送到远程配置中心,如Nacos。对远程配置中心进行监听,获取变更并完成本地配置更新

4.实现push模式
需要改动源码,详见: