一、初识Sentinel

1、雪崩问题及解决方案

1.1 雪崩问题

一个微服务故障宕机,其他微服务调用该宕机的微服务因此也会宕机,引起微服务连锁宕机的现象

  • 微服务间调用关系错综复杂,一个微服务往往依赖于多个其他微服务

    1.2 解决雪崩问题

    解决雪崩问题四种方式
  1. 超时处理
    • 设定超时时间,请求超时则返回错误信息,不用无休止等待
  2. 舱壁模式
    • 也叫线程隔离
    • 限制每个业务使用的线程数
  3. 熔断降级
    • 类似保险丝
    • 由断路器统计业务执行的异常比例
      • 超出阈值熔断该业务,拦截访问该业务的一切请求
  4. 流量控制
    • 限制业务访问的QPS(Query Per Second)

总结

  • 避免瞬间高并发流量导致服务故障
    • 流量控制
  • 避免因服务故障引起雪崩问题

    • 超时处理
    • 线程隔离
    • 熔断降级

      二、流量控制(限流规则)

      簇点链路(项目内的调用链路,链路中被监控的每个接口就是一个资源)
  • 默认情况下sentinel会监控SpringMVC的每一个端点

  • SpringMVC的每一个端点就是调用链路中的一个资源

    1、快速入门(略)

    2、流控模式

    三种流控模式
  1. 直接(默认模式)
    • 统计当前资源的请求,触发阈值时对当前资源直接限流
  2. 关联
    • 统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
    • 高优先级资源触发阈值,对低优先级资源限流
  3. 链路
    • 统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流
    • 只统计从指定资源进入当前资源的请求,是对请求来源的限流

      3、流控效果

      流控效果
  • 请求达到流控阈值时应该采取的措施

三种流控效果

  1. 快速失败(默认处理方式)
    • 达到阈值后,新的请求会被立即拒绝并抛出FlowException异常
    • QPS超过阈值时,拒绝新的请求
  2. warm up(预热模式)
    • 对超出阈值的请求同样是拒绝并抛出异常
    • 这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值
    • QPS超过阈值时,拒绝新的请求;QPS阈值是逐渐提升的,可以避免冷启动时高并发导致服务宕机
    • 举例
      • 设置QPS的threshold为10,预热时间为5秒,那么初始阈值就是 10 / 3 ,也就是3,然后在5秒后逐渐增长到10
  3. 排队等待
    • 让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长
    • 请求会进入队列,按照阈值允许的时间间隔依次执行请求;如果请求预期等待时长大于超时时间,直接拒绝
    • 举例
      • 设置QPS = 5,意味着每200ms处理一个队列中的请求
      • 设置timeout = 2000,意味着预期等待超过2000ms的请求会被拒绝并抛出异常

        4、热点参数限流

        限流是统计访问某个资源的所有请求,判断是否超过QPS阈值
        热点参数限流是分别统计参数值相同的请求,判断是否超过QPS阈值

        三、隔离和降级

        微服务出现故障不可避免,需要将故障控制在一定范围,避免雪崩
  • 线程隔离
  • 熔断降级

两者都是保护客户端(即微服务调用者)的

线程隔离的两种方式

  1. 线程池隔离
    • 基于线程池模式
      • 给每个微服务调用的业务分配一个线程池,利用线程池本身实现隔离效果
    • 优点
      • 隔离控制更强
  2. 信号量隔离(Sentinel默认使用)
    • 基于计数器模式
      • 不创建线程池,而是计数器模式
      • 记录业务使用的线程数量,达到信号量上限时,禁止新的请求
    • 优点
      • 轻量级
      • 适合高并发场景

线程隔离

  • QPS
    • 每秒的请求数
  • 线程数

    • 该资源能使用的tomcat线程数的最大值
    • 也就是通过限制线程数量

      3、熔断降级

      熔断降级
  • 由断路器统计服务调用的异常比例、慢请求比例

    • 如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求
    • 而当服务恢复时,断路器会放行访问该服务的请求

断路器控制熔断和放行是通过状态机来完成

  • 断路器状态
    • 断路器Closed
      • 请求正常
      • 断路器关闭状态,放行所有请求,统计异常比例、慢请求比例
      • 超过阈值则切换到Open状态
    • 断路器Open
      • 熔断降级
      • 所有请求直接降级快速失败
      • Open状态5秒后会进入Half-Open状态
    • 断路器Half-Open
      • 熔断时间结束,尝试放行请求
        • 放行成功则关闭熔断器
        • 放行失败则打开熔断器

断路器三种熔断策略

  1. 慢调用
    • 在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定的阈值,则触发熔断
  2. 异常比例
    • 统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例达到设定的比例阈值(或超过指定异常数),则触发熔断
    • 统计单位时长内异常调用的比例,超过阈值则熔断
  3. 异常数(跟异常比例雷同)
    • 统计单位时长内异常调用的次数,超过阈值则熔断

      四、授权规则

      授权规则
  • 对调用方的来源做控制

授权规则两种方式

  1. 白名单
    • 来源(origin)在白名单内的调用者允许访问
  2. 黑名单

    • 来源(origin)在黑名单内的调用者允许访问

      五、规则持久化

      1、规则管理模式

      Sentinel的控制台规则管理有三种模式
  3. 原始模式(Sentinel的默认模式)

    • 将规则保存在内存,重启服务会丢失
  4. pull模式
    • 保存在本地文件或数据库,定时去读取
  5. push模式
    • 保存在nacos,监听变更实时更新

      面试题

      1、微服务组件alibaba-sentinel介绍?

      微服务之间的依赖关系错综复杂,一个微服务往往依赖于多个其他微服务,一旦一个微服务故障宕机,其他微服务调用该宕机的微服务因此也会宕机,引起微服务连锁宕机的现象,微服务之间的稳定性则难以维持。
      alibaba-sentinel(阿里巴巴流量卫士)
  • 是阿里巴巴开源的面向分布式服务架构的流量控制组件
  • 以流量为切入点,从多个纬度维护微服务的稳定性

    • 是预防措施,避免因瞬间高并发导致微服务故障,避免引起雪崩
      • 流量控制
    • 是补救措施,在部分微服务故障时,将故障控制在一定范围,避免引起雪崩
      • 超时处理
      • 线程隔离
      • 熔断降级

        2、Sentinel中限流功能介绍? 支持的限流规则?

        限流功能
  • 限制业务访问的QPS(每秒访问次数),避免因访问流量徒增导致微服务故障

限流规则

  • 三种流控模式
    1. 直接(默认模式)
      • 统计当前资源的请求,触发阈值时对当前资源直接限流
    2. 关联
      • 统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
      • 高优先级资源触发阈值,对低优先级资源限流
    3. 链路
      • 统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流
      • 只统计从指定资源进入当前资源的请求,是对请求来源的限流

        3、Sentinel线程隔离介绍?

        线程隔离的两种方式
  1. 线程池隔离
    • 基于线程池模式
      • 给每个微服务调用的业务分配一个线程池,利用线程池本身实现隔离效果
    • 优点
      • 隔离控制更强
  2. 信号量隔离(Sentinel默认使用)
    • 基于计数器模式
      • 不创建线程池,而是计数器模式
      • 记录业务使用的线程数量,达到信号量上限时,禁止新的请求
    • 优点
      • 轻量级
      • 适合高并发场景

        4、Sentinel断路器功能介绍?

        熔断降级
  • 由断路器统计服务调用的异常比例、慢请求比例
    • 如果超出阈值则会熔断该服务
      • 即拦截访问该服务的一切请求
    • 当服务恢复时,断路器会放行访问该服务的请求

断路器控制熔断和放行是通过状态机来完成

  • 断路器状态
    • 断路器Closed
      • 请求正常
      • 断路器关闭状态,放行所有请求,统计异常比例、慢请求比例
      • 超过阈值则切换到Open状态
    • 断路器Open
      • 熔断降级
      • 所有请求直接降级快速失败
      • Open状态5秒后会进入Half-Open状态
    • 断路器Half-Open
      • 熔断时间结束,尝试放行请求
        • 放行成功则关闭熔断器
        • 放行失败则打开熔断器

          5、Feign + Sentinel实现服务降级配置?

          步骤
  1. 修改微服务调用者的配置文件application.yml,开启Feign的Sentinel功能

    1. feign:
    2. sentinel:
    3. enabled: true # 开启feign对sentinel的支持
  2. 给FeignClient编写失败后的降级逻辑

    1. 方式一:FallbackClass
      • 无法对远程调用的异常做处理
    2. 方式二:FallbackFactory(推荐)

      • 可以对远程调用的异常做处理
      1. Feign模块编写类实现接口FallbackFactory

        @Slf4j
        public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
        @Override
        public UserClient create(Throwable throwable) {
        return new UserClient() {
        @Override
        public User findById(Long id) {
            log.error("查询用户异常", throwable);
            return new User();
        }
        };
        }
        }
        
      2. 将改FallbackFactory注册在Feign模块的Feign配置类中

        public class DefaultFeignConfiguration {
        @Bean
        public UserClientFallBack userClientFallBack(){
        return new UserClientFallBack();
        }
        }
        
      3. 将FallbackFactory配置到FeignClient
        ```java @FeignClient(value = “userservice”, fallbackFactory = UserClientFallbackFactory.class) public interface UserClient {

    @GetMapping(“/user/{id}”) User findById(@PathVariable(“id”) Long id); } ```