Sentinel

简介: Sentinel

Sentinel


1、运行

命令:

java -jar sentinel-dashboard-1.7.0.jar

yml:


server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: '*'
feign:
  sentinel:
    enabled: true # 激活Sentinel对Feign的支持


访问前台界面:

http://localhost:8080

,Sentinel使用的是懒加载,只有当真正访问业务的时候才会监控。

image.png


2、Sentinel流量控制(流控)

1、QPS直接失败

image.png

QPS是一秒内访问数,超过设置的阈值将会报错

image.png

思考

直接调用默认报错信息,技术方面OK,但是,是否应该有我们自己的后续处理?类似有个fallback的兜底方法?


2、线程数直接失败

线程数:当调用该API的线程数达到阈值的时候,进行限流。

image.png

3、关联

是什么?

当自己关联的资源达到阈值时,就限流自己

当与A关联的资源B达到阀值后,就限流A自己(B惹事,A挂了)

设置testA

当关联资源/testB的QPS阀值超过1时,就限流/testA的Rest访问地址,当关联资源到阈值后限制配置好的资源名。

image.png

用postman发送,启用20个进程,每隔0.3秒访问一次,

image.pngimage.png


4、预热

默认coldFactor为3,即请求QPS 从 threshold / 3开始,经预热时长逐渐升至设定的QPS阈值

image.png

WarmUp配置


案例,阀值为10,预热时长设置5秒。

系统初始化的阀值为10/ 3约等于3,即阀值刚开始为3;然后过了5秒后阀值才慢慢升高恢复到10

image.png

测试

多次快速点击http://localhost:8401/testB - 刚开始不行,后续慢慢OK

应用场景

如:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值。


5、排队等待

匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效。

设置:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。

image.png

6、Sentinel降级

image.png

RT(平均响应时间,秒级)


平均响应时间 超出阈值 且 在时间窗口内通过的请求>=5,两个条件同时满足后触发降级。

窗口期过后关闭断路器。

RT最大4900(更大的需要通过-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)。

异常比列(秒级)


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

异常数(分钟级)


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

Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。


当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。


Sentinei的断路器是没有类似Hystrix半开状态的。(Sentinei 1.8.0 已有半开状态)


半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。


1、Sentinel降级-RT

设置RT为0.2秒,时间窗口是1秒

image.png

image.png

在jmeter设置一秒发10个线程,这样必然会导致系统崩溃

image.png

image.png

image.png


2、异常比例

是什么?


异常比例(DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量 >=

5,并且每秒异常总数占通过量的比值超过阈值( DegradeRule中的 count)之后,资源进入降级状态,即在接下的时间窗口(

DegradeRule中的timeWindow,以s为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0,

1.0],代表0% -100%。


注意,与Sentinel 1.8.0相比,有些不同(Sentinel 1.8.0才有的半开状态),Sentinel 1.8.0的如下:


异常比例

(ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN

状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% -

100%。


设置异常超过百分之20,3秒内不可用

image.png

按照上述配置,单独访问一次,必然来一次报错一次(int age = 10/0),调一次错一次。


开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了。断路器开启(保险丝跳闸),微服务不可用了,不再报错error而是服务降级了。


3、异常数

是什么?

异常数( DEGRADE_GRADF_EXCEPTION_COUNT ):当资源近1分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若timeWindow小于60s,则结束熔断状态后码可能再进入熔断状态。

image.png

当发生异常数后,要在时间窗口后规定的时间后才能正常访问。


7、Sentinel热点key(上)

兜底方法,分为系统默认和客户自定义,两种


之前的case,限流出问题后,都是用sentinel系统默认的提示: Blocked by Sentinel (flow limiting)


我们能不能自定?类似hystrix,某个方法出问题了,就找对应的兜底降级方法?


结论 - 从HystrixCommand到@SentinelResource


@RestController
@Slf4j
public class FlowLimitController
{
    ...
    @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler/*兜底方法*/ = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2",required = false) String p2) {
        //int age = 10/0;
        return "------testHotKey";
    }
    /*兜底方法*/
    public String deal_testHotKey (String p1, String p2, BlockException exception) {
        return "------deal_testHotKey,o(╥﹏╥)o";  //sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
    }
}


配置

image.png

image.png



8、Sentinel热点key(下)(参数例外项)

image.png

配置

image.png

总结

image.png


8、Sentinel系统规则

简单的说就是系统级别的规则,单系统访问量达到一定级别时候,整个系统就访问不了了

image.png

image.png


参数解读:

image.png


9、SentinelResource配置(上)

Sentinel相当于HystrixCommand

@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 服务不可用");
    }


设置流控,当一秒内访问数大于1时,就会走到我们自定义的方法里面

image.png

image.png

此时如果关闭8804服务,流控规则会消失吗?

image.png

可以看出,当关闭服务后,流控规则也消失了,那么怎样才能让流控规则持久化呢?


上面兜底方案面临的问题

1.系统默认的,没有体现我们自己的业务要求。

2.依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观。

3.每个业务方法都添加—个兜底的,那代码膨胀加剧。

4.全局统—的处理方法没有体现。

10、SentinelResource配置(下)

解决思路是自己创建一个类,这个类里面有很多处理的方法,然后SentinelResource调用。

image.png

public class CustomerBlockHandler
{
    public static CommonResult handlerException(BlockException exception)
    {
        return new CommonResult(4444,"按客戶自定义,global handlerException----1");
    }
    public static CommonResult handlerException2(BlockException exception)
    {
        return new CommonResult(4444,"按客戶自定义,global handlerException----2");
    }
}


业务代码:


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

结果截图:

image.png


11、Sentinel服务熔断

image.png

image.png

12、fallback

@RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
    public CommonResult<Payment> fallback(@PathVariable Long id)
    {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id);
        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);
    }

image.png

13、blockhander

blocker不管java运行时异常,只管并发访问异常。

public CommonResult blockHandler(@PathVariable  Long id,BlockException blockException) {
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);
    }

这将代替sentinel默认的异常输出

14、fallback和blockhander

image.png

15、exceptionsToIgnore

@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
            exceptionsToIgnore = {IllegalArgumentException.class})
     public CommonResult<Payment> fallback(@PathVariable Long id)
    {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id);
        if (id == 4) {
            throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
        }else if (result.getData() == null) {
            throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
        }
        return result;
    }

忽略指定的异常,也就是输入4异常处理忽略。

image.png

image.png


16、Sentinel服务熔断OpenFeign

84消费者调用提供者9003


Feign组件一般是消费侧


POM

<!--SpringCloud openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>


YML


<!--SpringCloud openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>


业务类


带@Feignclient注解的业务接口,fallback = PaymentFallbackService.class


import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
public interface PaymentService
{
    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.stereotype.Component;
@Component
public class PaymentFallbackService implements PaymentService {
    @Override
    public CommonResult<Payment> paymentSQL(Long id)
    {
        return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
    }
}

Controller

@RestController
@Slf4j
public class CircleBreakerController {
    ...
  //==================OpenFeign
    @Resource
    private PaymentService paymentService;
    @GetMapping(value = "/consumer/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id)
    {
        return paymentService.paymentSQL(id);
    }
}


测试 - http://localhost:84/consumer/paymentSQL/1

测试84调用9003,此时故意关闭9003微服务提供者,84消费侧自动降级,不会被耗死。

image.png

熔断框架比较

image.png


17、Sentinel持久化规则

是什么

一旦我们重启应用,sentinel规则将消失,生产环境需要将配置规则进行持久化。

怎么玩

将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel上的流控规则持续有效。

步骤

修改cloudalibaba-sentinel-service8401


POM

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

YML


server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719
      datasource: #<---------------------------关注点,添加Nacos数据源配置
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: '*'
feign:
  sentinel:
    enabled: true # 激活Sentinel对Feign的支持


添加Nacos业务规则配置

image.png

配置内容解析

[{
    "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表示Warm Up,2表示排队等待;


启动8401后刷新sentinel发现业务规则有了

image.png

相关文章
|
6月前
|
负载均衡 监控 Java
Sentinel介绍与使用
Sentinel介绍与使用
390 3
|
6月前
|
算法 网络协议 安全
深入理解Sentinel系列-1.初识Sentinel
深入理解Sentinel系列-1.初识Sentinel
305 1
深入理解Sentinel系列-1.初识Sentinel
|
Dubbo Java 应用服务中间件
springcloud sentinel
springcloud sentinel
80 0
|
监控 Dubbo Java
Sentinel介绍及搭建
Sentinel介绍及搭建
318 0
|
监控 Dubbo Java
超详细的Sentinel入门
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
超详细的Sentinel入门
|
SpringCloudAlibaba 运维 监控
详解sentinel使用
1.概述 sentinel,springcloud alibaba中对标springcloud Netflix中的hystrix的组件,是一个强大的分布式系统保护工具,通过流量控制、熔断降级和系统负载保护等机制,保障了微服务架构的稳定性和可用性。它是Spring Cloud生态系统中的重要组件之一,被广泛应用于微服务开发和运维中。阿里每年的“双十一”,sentinel就是提供分布式保护机制的核心组件之一。
507 0
|
自然语言处理 Java 数据安全/隐私保护
Springcloud之Sentinel服务容错
Springcloud之Sentinel服务容错
|
监控 Dubbo Java
【Sentinel】初识Sentinel
【Sentinel】初识Sentinel
435 0
【Sentinel】初识Sentinel
|
算法 Sentinel
Sentinel学习二
如果我们不对Sentinel的异常提示做自定义,那么此时的提示是非常不详细的。如果做了自定义,就可以看到下面自定义的提示。sentinel提供了@SentinelResource注解帮助我们来实现自定义的熔断限流后的自定义方法处理,可以根据sentinel的aop可以看到处理的example,从而更为清晰的认识sentinel强大的功能。
109 0
Sentinel学习二
|
监控 Dubbo Java
SpringCloud Sentinel 使用
在以后我们的项目部署上线的时候,会有各种各样的服务突发问题,比如雪崩效应(在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致服务瘫痪。由于服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的雪崩效应)等问题。
209 0
SpringCloud Sentinel 使用