SpringCloud-Alibaba-Sentinel

1 Overview

Sentinel,中文翻译为哨兵,是为微服务提供流量控制、熔断降级的功能,它和Hystrix提供的功能一样,可以有
效的解决微服务调用产生的“雪崩”效应,为微服务系统提供了稳定性的解决方案。随着Hytrxi进入了维护期,不
再提供新功能,Sentinel是一个不错的替代方案。通常情况,Hystrix采用线程池对服务的调用进行隔离,
Sentinel才用了用户线程对接口进行隔离,二者相比,Hystrxi是服务级别的隔离,Sentinel提供了接口级别的
隔离,Sentinel隔离级别更加精细,另外Sentinel直接使用用户线程进行限制,相比Hystrix的线程池隔离,减
少了线程切换的开销。另外Sentinel的DashBoard提供了在线更改限流规则的配置,也更加的优化。

从官方文档的介绍,Sentinel 具有以下特征:

丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控
制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,
甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、
gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻
辑。例如定制规则管理、适配数据源等。


 

2. Basic use

1、新建项目,添加pom依赖
    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>

2、编写配置文件
server:
  port: 9003
spring:
  application:
    name: cloud-sentinel-9003
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
    nacos:
      discovery:
        server-addr: xxx.xxx.xxx.xxx:8848
management:
  endpoints:
    web:
      exposure:
        include: "*"
***在这里,sentinel运行在本地,尝试使用docker,但是获取不到服务的详细链路,原因是sentinel主动向服务拉取信息,阿里云服务器无法访问到本机,因此失败。

3、启动项目后,访问两个端口/testA和/testB,刷新sentinel即可看到

3. Flow control rules

3.1, QPS fails directly and quickly

If it is accessed more than five times per second, an exception will be thrown

3.2 The number of threads directly fails

When the number of threads calling the interface exceeds the threshold, the current is limited,

3.3 Association

When HelloA is accessed more than once per second, HelloB will be limited. For example, when the payment service is full, the order service will be limited to prevent collateralization.

3.4 Link

The link flow control mode means that when the resource from a certain interface reaches the current limit condition, the current limit is turned on; its function is similar to the configuration item for the source, the difference is: the source is for the upper-level microservice, and Link flow control is for the upper-level interface, which means that its granularity is finer;

Create a service, add annotations

@SentinelResource(value = "getOrder",blockHandler = "handlerException")

Set in the flow monitoring place:

Access to HelloB more than once per second will limit the flow.

Note: After sentinel1.7, you need to set spring.cloud.sentinel.web-context-unify=false

Details: https://github.com/alibaba/Sentinel/issues/1213

3.5 Warm up

The QPS per second within 5 seconds of warm-up is at most 10/3=3 times. If it exceeds 3 times, the current will be limited. After 5 seconds, the threshold will be restored to 10

3.6 Waiting in line

HelloA processes a request once a second, and waits in a queue if it exceeds the waiting time. The waiting timeout period is 2000 milliseconds. If the waiting time exceeds the waiting millisecond, the flow will be limited.

4. Service degradation

1、RT(平均响应时间,秒级)
    平均响应时间超出阀值且在时间窗口内通过的请求次数>=5次,两个条件同时满足后触发降级
    窗口期过后关闭断路器,RT最大4900

2、异常比例(秒级)
    QPS>=5且异常比例(秒级统计)超过阀值时,触发降级,时间窗口期结束后,关闭降级

3、异常数(分钟级)
    异常数(分钟统计)超过阀值时,触发降级;时间窗口结束后,关闭降级

4.1RT

Entering >= 5 requests in one second, if the average response time is greater than 200 milliseconds, the circuit breaker will be turned on, and the downgrade will be turned off after the time window is 2 seconds.

4.2 Anomaly ratio

Continue to enter >=5 requests per second. If the abnormal rate of requests processed per second is greater than 20%, turn on the circuit breaker, and turn off the downgrade after the time window is 2 seconds.

4.3 Number of exceptions

Number of exceptions (DEGRADE_GRADE_EXCEPTION_COUNT): When the number of exceptions in the last minute of the resource exceeds the threshold, it will be blown. Note that because the statistical time window is at the minute level, if the timeWindow is less than 60s, it may enter the fusing state again after the fusing state is ended.

The number of abnormalities is counted in minutes, so the time window must be greater than or equal to 60s

If the abnormality exceeds 5 times within 61 seconds, turn on the circuit breaker, and close the circuit breaker after 61 seconds

5. Hot Key

@GetMapping("/HelloE")
@SentinelResource(value = "helloE",blockHandler = "hostKeyHandler")
public String getE(@RequestParam(value = "a",required = false)String a
                  ,@RequestParam(value = "b",required = false)String b)
{
    return "------HelloE------";
}
public String hostKeyHandler(String a, String b, BlockException ex){
    return ex.getRule().getResource()+",服务正忙,稍后再试~";
}

For the HelloE request, the first parameter carried, if the QPS exceeds 1, it will be downgraded and return custom information

Add parameter exception items, set if the first parameter is 2, the threshold is 10, and the first parameter is not 2, then the threshold is 1.

6. System rules

Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 
RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达
到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性
Field Description Defaults
highestSystemLoad load1 Trigger value, used to trigger the adaptive control phase -1 (not effective)
avgRt Average response time of all inlet flows -1 (not effective)
maxThread Maximum concurrent number of ingress traffic -1 (not effective)
qps QPS of all ingress resources -1 (not effective)
highestCpuUsage The CPU usage of the current system (0.0-1.0) -1 (not effective)

When any request to access the system QPS exceeds 1, the circuit breaker will be opened

7、SentinelResource

7.1 Current limiting based on resource name

@GetMapping("/byResource")
@SentinelResource(value = "byResource",blockHandler = "handleException")
public CommonResult byResource()
{
    return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001"));
}
public CommonResult handleException(BlockException exception)
{
    return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");
}

Limit current according to the value annotated by SentinelResource

7.2 Current limit based on URL

@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl")
public CommonResult byUrl()
{
    return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002"));
}

Limit the current according to Url, but use Sentinel's own prompt information, which is not friendly

7.3 Custom current limit processing logic

@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
        blockHandlerClass = CustomerBlockHandler.class,
        blockHandler = "handlerException2")
public CommonResult customerBlockHandler()
{
    return new CommonResult(200,"按客戶自定义",new Payment(2020L,"serial003"));
}
public class CustomerBlockHandler {
  public static CommonResult handlerException2(BlockException exception)
  {
     return new CommonResult(4444,"按客戶自定义,global handlerException----1");
  }

Separate the processing of the downgrade prompt information from the business logic, and use blockHandlerClass and blockHandler to specify the class name and method name

SentinelResouce cannot monitor private methods

8. Service fusing

1、新建两个服务提供者和一个消费者,将其注册到nacos

2、分别通过Ribbion和OpenFeign调用服务

pom依赖
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

8.1@SentinelResource only configure value

After the value is flow controlled, a 500 error will be reported

8.2@SentinelResource only configure fallback

Only downgrade system exceptions, and will not cover the flow control and downgrade set by sentinel

8.3@SentinelResource only configures blockhandler

Only the flow control and downgrade set by sentinel will be dealt with, and the system will not be downgraded.

8.3 @SentinelResource configure fallback and blockhandler

The flow control and degradation of exceptions and sentinel settings will be handled differently

8.4 Configure exceptionsToIgnore in @SentinelResource

Ignore the set exceptions, and will not deal with it, you can write the global exception handling class for processing

8.5 OpenFeign separates the downgrade logic from the business logic by adding annotations to the interface

Create a new class to implement the interface, perform downgrade processing in the overloaded method, and add fallback = xxx.class to the annotation of the interface

Note that you need to add @Component to the implementation class, otherwise an error will be reported

@RestController
@Slf4j
public class OrderController {

    @Resource
    private OrderService orderService;

    @Autowired
    private RestTemplate restTemplate;

    @Value("${service.url.paymentUrl}")
    private String paymentUrl;

    // ----------OpenFeign-----------
    @GetMapping("/consumer/getByFeign/{id}")
    public CommonResult getPayByFeign(@PathVariable("id") Long id){
        log.info("**************OpenFeign");
        CommonResult<Payment> result = orderService.paymentSQL(id);
        if (id == 4) {
            throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
        }else if (result.getData() == null) {
            throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
        }
        return result;
    }
    // ----------Ribbion-----------
    @GetMapping("/consumer/getByRibbion/{id}")
    //@SentinelResource(value = "fallback")
    //@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
    //@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
    @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
            exceptionsToIgnore = {IllegalArgumentException.class})
    public CommonResult getByRibbion(@PathVariable("id") Long id){
        log.info("**************Ribbion");
        CommonResult result = restTemplate.getForObject(paymentUrl + "/payment/" + id, CommonResult.class);
        if (id == 4) {
            throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
        }else if (result.getData() == null) {
            throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
        }
        return result;
    }
    //本例是fallback
    public CommonResult handlerFallback(@PathVariable  Long id,Throwable e) {
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(444,"兜底异常handlerFallback,exception内容  "+e.getMessage(),payment);
    }
    //本例是blockHandler
    public CommonResult blockHandler(@PathVariable  Long id, BlockException blockException) {
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);
    }

}


------------------------------------------------------------
@Component
@FeignClient(value = "cloud-sentinel-payment-provider",fallback = OrderSerivceHandler.class)
public interface OrderService {

    @GetMapping(value = "/payment/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);

}

-----------------------------------------------------------------
@Component
public class OrderSerivceHandler implements  OrderService {
    @Override
    public CommonResult<Payment> paymentSQL(Long id) {
        return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
    }
}

9. Persistence rules

Store the current limiting configuration persistently in Nacos

1、添加pom依赖
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>

2、在项目配置文件里添加配置如下
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
      datasource:
        wx1: #名字随意起
          nacos:
            server-addr: xxx.xxx.xxx.xxx:8848 #nacos地址
            dataId: cloud-alibaba-sentinel-service #配置文件的dataId
            groupId: DEFAULT_GROUP #配置文件的分组
            data-type: json #配置文件的类型
            rule-type: flow #用来定义存储的规则类型,flow代表限流规则
                            #degrade代表降级
                            #system代表系统规则
                            #authority代表授权
3、在Sentinel添加配置文件如下图

4、规则说明
resource:资源名称
limitApp:来源应用
grade:阀值类型,0代表线程数,1代表QPS
count:单机阀值
strategy:流控模式,0代表直接,1代表关联,2代表链路
controlBehavior:流控效果,0代表快速失败,1代表Warm Up(预热),2代表排队等待
clusterMode:是否集群,false代表没有,true代表集群

6、监控数据说明
流控的数据只会保存5分钟,如果想持久化,可以后期使用:
    1.实现 MetricsRepository 接口;
    2.注册成 Spring Bean 并在相应位置通过 @Qualifier 注解指定对应的 bean name 即可。


 

10. Other instructions

1、sentinel数据持久化有五种方式
    1.File 2.Redis 3.Nacos 4.Zookeeper 5.apollo

2、sentinel默认监控数据只保存五分钟,如果想要对监控的数据情况持久化有以下两种方式
    1.自行扩展实现 MetricsRepository 接口;
    2.注册成 Spring Bean 并在相应位置通过 @Qualifier 注解指定对应的 bean name 即可。
    

 

Guess you like

Origin blog.csdn.net/wx774891/article/details/106979572