Sentinel

雪崩问题

微服务调用链路中的某个服务故障满,引起整个链路中的所有微服务都不可用 ,这就是雪崩。

解决方案:
1.超时处理: 设定超时时间,请求一定时间没有响应就返回错误信息,不会无休止等待

2.舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离

3.熔断降级: 由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求

4.流量控制:限制业务访问的QPS,避免服务因流量的突增而故障

前三种是已经发生故障,怎么样去避免故障传递
第四种是避免发生故障 ,属于预防的解决方案

如何避免因瞬间高并发流量而导致服务故障?

  • 流量控制

如何避免因服务故障引起的雪崩问题?

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

服务保护技术对比:

安装sentinel-dashboard

1.下载jar 包,地址:https://github.com/alibaba/Sentinel/releases

  1. 启动,默认端口8080.初始密码:sentinel/sentinel
PS E:\javaProject\sentinel> java -jar .\sentinel-dashboard-1.8.1.jar

修改默认端口:java -jar .\sentinel-dashboard-1.8.1.jar --server.port=8899

3.访问成功

微服务整合sentinel

步骤:
1.order-service 中引入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2.sentinel 中加入sentinel配置:

spring:
  cloud:
    # 配置sentinel 相关信息
    sentinel:
      transport:
        dashboard: localhost:8899 # 控制台的地址

3.调用多次order-service服务

4.sentinel 服务台中查看请求监控信息

限流规则

快速入门

簇点链路:就是项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下sentinel 会监控SpringMVC 的每一个端点(Endpoint) 也就是controller层中的每个方法,因此SpringMVC 的每个一端点(Endpoint) 就是调用链路中的一个资源

点击资源/order/{orderId} 后面的流控按钮,就可以添加流控规则

其含义是限制/order/{orderId}这个资源的单机QPS为1,即每秒只允许1次请求,超出的请求会被拦截

需求:给/order/{orderId} 设置流控规则,QPS不能超过5,然后利用jmeter进行测试

测试:

线程组配置:2s内发送20个请求

执行结果:
1s 内只能处理5个请求,限流成功

失败的请求返回:

sentinel 监控结果:

流控模式

在添加限流规则时,点击高级选项,可以选择三种流控模式:

  • 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
  • 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
  • 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流

关联模式

使用场景:比如用户支付时需要修改订单的状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是有支付和更新订单的业务,因此当修改订单发出阈值时,需要对查询订单业务限流

当/write 资源访问量触发阈值时,就会对/read 资源限流,避免影响/write 资源

需求: 在orderContoller 新建两个端点: /order/query 和 /order/update,无需实现业务,配置流控规则,当/order/update 资源被访问的QPS超过5时,对/order/query 请求限流

1.controller 层新加方法:

@GetMapping("query")
public String queryOrder(){
    return "查询订单";
}

@GetMapping("update")
public String updateOrder(){
    return "更新订单";
}

2.新建限流规则:当update 达到阈值5时,对query 限流

3.使用jmeter 使用QPS 为10 ,持续访问 /order/update

3.1 固定量吞吐定时器设置:10 * 60 = 600

3.2 线程组设置:

访问/order/query 时 已经被限流

sentinel 监控:

小结:
满足下面条件可以使用关联模式:

  • 两个有竞争关系的资源
  • 一个优先级高,一个优先级较低

链路模式

链路模式:只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值.

例如有两条请求链路:

  • /test1 -> /common
  • /test2 -> /common

如果只希望统计从/test2 进入到/common 的请求,则可以这样配

案例:有查询订单和创建订单业务,两者都需要查询商品。针对从查询订单进入到查询商品的请求统计,并设置限流,从/order/query 进入queryGoods 的方法限制QPS 必须小于2

前置代码:
controller:

@RestController
@RequestMapping("/order")
public class OrderController {

   @Autowired
   private OrderService orderService;


    @GetMapping("/query")
    public String queryOrder(){
        orderService.queryGoods();
        System.out.println("查询商品");
        return "查询订单";
    }

    @GetMapping("/save")
    public String saveOrder(){
        orderService.queryGoods();
        System.out.println("查询商品");
        return "新增订单";
    }

}

service:


@Service
public class OrderService {
    @SentinelResource("goods")
    public void queryGoods(){
        System.out.println("查询商品");
    }
}

实现步骤:

  1. queryGoods 方法加入注解,让sentinel监控到
@SentinelResource("goods")
public void queryGoods(){
    System.out.println("查询商品");
}

  1. sentinel 默认会将Controller方法做context整合,导致链路模式的流控失效,需要修改appliction.yml,添加配置
spring:
  cloud:
    # 配置sentinel 相关信息
    sentinel:
      transport:
        dashboard: localhost:8899 # 控制台的地址
      web-context-unify: false # 关闭context 整合

3.创建限流规则:

  1. 每个接口以 4 QPS 请求

发现/order/query 会请求失败两个:

sentinel 实施监控结果:
goods为 6QPS,一共8QPS,/order/query 被限流为2QPS


流控效果

warm up

warm up 也叫预热模式,是应对服务冷启动的一种方案。请求阈值初始值是 threshold / coldFactor, 持续指定时长后,逐渐提高到threshold。而 coldFactor 的默认值是3
例如:设置QPS 的 threshold 为10,预热时间为5秒,那么初始阈值就是 10/3,也就是3, 然后在5秒后逐渐增长到10QPS

需求:给/order/{orderid}这个资源设置限流,最大QPS为10,利用warm up 效果,预热时长为5s

创建流控:

Jmeter 配置 10QPS:

Jmeter 结果:

Sentinel结果:

排队等候

当请求超过QPS阈值时,快死失败和warm up 会拒绝新的请求并抛出异常。而排队等候则是让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。后来的请求必须等待前面执行完成,
如果请求预期的等待超过最大时长,则会被拒绝

例如:QPS=5,意味着每200ms处理一个请求,如果timeout=2000,意味着队列最多可以放入10个请求,预期等待超过2000ms的请求会被拒绝并抛出异常

需求:给/order/{orderid}这个资源设置限流,最大QPS 为10,利用排队的流控效果,超时时长设置为5s

Jmeter 配置 15QPS:

执行结果:

Sentinel 监控:

可以看到QPS处于一个相对平缓的状态,这样对微服务是一种保护作用

热点参数

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

配置示例:

代表的含义:对hot这个资源的0号参数(请求参数列表的第一个参数) 做统计,每1秒相同数值的请求数不能超过5个

在热点参数的限流的高级选项中,可以对部分参数设置例外配置:

  • 如果参数值是100,则每1秒允许的QPS为10
  • 如果参数值是101,则每1秒允许的QPS为15

案例:
给/order/{orderid} 这个资源添加热点参数限流,规则如下:

  • 默认的热点参数规则是每1秒请求量不超过2
  • 给102这个参数值设置例外:每1秒请求量不超过4
  • 给102这个参数值设置例外:每1秒请求量不超过10

实现步骤:
1.给接口加上注解

  1. sentinal 控制台添加规则:

具体规则:

3.jmter 模拟请求

请求结果:

sentinel 实施监控:

可以看到最大QPS为11,因为一个2一个4一个5

posted @ 2023-10-04 11:01  chuangzhou  阅读(7)  评论(0编辑  收藏  举报