Sptring cloud Alibaba Sentinel 实现熔断与限流

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。

Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

 

作用:

服务雪崩

服务降级

服务熔断

服务限流

 

1.cmd  java -jar sentinel-dashboard-1.6.3.jar

2.打开nacos

3.访问http://localhost:8080

  <dependencies>
        <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件+actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--日常通用jar包配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
server:
  port: 8401


spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080 #配置sentinel dashbord地址
        port: 8719


management:
  endpoints:
    web:
      exposure:
        include: "*"

这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。
比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。

package com.etc.cloudalibaba.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class FlowLimitController {
    @GetMapping("/testA")
    public String testA(){
        return "------ testA -----";
    }

    @GetMapping("/testB")
    public String testB(){
        return "------ testB -----";
    }
    /**
     * 主要测试降级  ----   RT
     * @return
     */
    @GetMapping("/testC")
    public String testC(){
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "------ testC -----" ;
    }


    /**
     * 主要测试降级  ----   异常占比   异常数
     * @return
     */
    @GetMapping("/testD")
    public String testD(){
        System.out.println(10/0);
        return "------ testD -----" ;
    }
}
package com.etc.cloudalibaba;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@Slf4j
@SpringBootApplication
@EnableDiscoveryClient
public class SentinelServiceMain8401 {
    public static void main(String[] args) {
        SpringApplication.run( SentinelServiceMain8401.class,args);
        log.info("****************SentinelServiceMain8401 启动 ************ ");
    }
}

sentinel 采用懒加载方式 。

 

流控规则

 

 

资源名 唯一名称 默认请求路径

针对来源 Sentinel 可以针对调用者限流 填写微服务名 默认 default 不区分来源

阈值类型 /单机阈值

  • QPS (每秒请求的数量) 当调用该api的qps 达到阈值的时候进行限流

  • 线程数 : 当调用该api的线程数达到阈值的时候 进行限流

流控模式

  • 直接 api达到限流的直接限流

  • 关联 当关联的资源达到阈值时。 就限流自己,当A关联了B , B 达到阈值的之后就限流自己

  • 链路 只记录链路上的流量指定资源从入口资源进来的流量。 如果达到阈值就限流 api级别针对来源

 

流控效果

  • 快速失败 直接失败。 抛异常

  • Warm up 冷加载因子。 默认时3,公式阈值除3(默认3), 经过预热时长后才会达到的阈值。 100 /3 = 33 慢慢升上来 预热时长我们配置 4秒

  • 排队等待 匀速排队让请求 匀速通过。 这个阈值类型只能是qps,阈值必须是设置为qps 均匀排队 方式会严格控制请求的时间间隔。 让请求以均匀的速度通过 。 对应漏斗算法。

 

降级规则

 

RT

平均响应时间: 当1s内持续进入5个请求,对应时刻的平均响应时间均超过阈值 毫秒那么在接下来的时间窗口 之内。 对这个方法的调用都自动熔断。

/**
 * 主要测试降级  ----   RT
 * @return
 */
@GetMapping("/testC")
public String testC(){
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "------ testC -----" ;
}

配置:类型 RT RT 200毫米 时间窗 4 s

如果QPS大于5, 并且平均响应时间大于200ms, 在接下来4s钟无法访问,之后恢复。

异常比例

 当资源的每秒请求量>=5,并且每秒异常总数占通过率的比值超过阈值。 就引入降级状态在接下来的时间窗口之内对这个方法都进行自动返回。 异常比例 0.0 1.0 代表 0% 100%

异常数

当资源近1分钟的异常超过我们设定阈值之后进行熔断。 注意统计时间窗口分钟级别。 若 小60s 择结果熔断后仍可能在进入熔断。

热点key限流

异常数据可以不可自定义 Blocked by Sentinel (flow limiting)

@GetMapping("/testHotykey")
@SentinelResource(value = "testHotykey",blockHandler = "deal_testHotykey")
public String testHotykey(
                           @RequestParam(value = "p1",required = false) String p1,
                           @RequestParam(value = "p2",required = false) String p2){

    return "-------  testHotykey ------- ";

}


public String deal_testHotykey(String p1, String p2, BlockException e){
    return "-------- deal_testHotykey   兜底了---------";
}

 

 

系统规则

LOAD 自适应 : 系统的load 1 作为一个启发的指标。 进行自适应系统保护。 当系统load1 超过设定的其法制。 cpu cores * 2.5

RT 当单台机器上所有入口流量的平均rt 达到阈值触发系统保护。 单位是毫米。

线程数 当单台机器上所有的入口的流量的并发线程达到我们阈值的时候触发系统保护

入口 QPS 当单台机器的素偶u的入口的流量达到qps 触发系统保护

CPU 使用率 当系统cpu使用率超过阈值就马上触发系统保护

 

不合适 使用危险 一个竹竿打死了一片人

 

规则持久化

 一旦我们重新启动机器。 sentinel规则消息。 生成环境种需要配置的规则进行持久化。

将限流的规则保存在nacos上

 引入pom

<!--     sentinel-datasource-nacos 后续持久化用   -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

改yml

 

编写json

[
    {
        "resource": "/rateLimit/byUrl",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

resource 资源名

limitApp 来源应用

grade 阈值类型 0 线程数 1 qps

count 阈值数量

strategy 流控模式 0 直接 1 关联 2 链路

controlBehavior 流控效果 0 快速失败 1 预热 2 排队等待

clusterMode 是否是集群

posted @ 2020-08-30 09:05  neona  阅读(212)  评论(0编辑  收藏  举报