SpringCloudAlibaba之Sentinel(一)流控篇

 前言:

为什么使用Sentinel,这是一个高可用组件,为了使我们的微服务高可用而生

我们的服务会因为什么被打垮?

一,流量激增    缓存未预热,线程池被占满 ,无法响应

二,被其他服务拖垮,比如第三方的接口响应慢

三,异常没有处理:缓存击穿,缓存穿透等等

总之而言:系统缺乏可用性防护,没有容错机制,尤其是针对流量的防护会降低服务的可用性

服务雪崩:首先是积分系统服务挂掉了,一个系统不可用,导致整个微服务系统都不可用

 限制流量

熔断

服务的降级   A计划-->B计划   积分服务就是一个弱依赖,和整体的流程关联不大,挂掉了也不会影响什么

有很多组件可以让我们进行流控、熔断、及降级,从中我们选择了SpringCloudAlibaba为我们提供的Sentinel这个组件作为我们项目中的保证服务高可用的组件。

SpringCloudAlibaba之Sentinel(一)流控篇_第1张图片

https://github.com/alibaba/spring-cloud-alibaba/wiki

sentinel的说明文档

https://github.com/alibaba/spring-cloud-alibaba/blob/2.2.x/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md

sentinel的控制台

https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0

先了解一下如何接入 Sentinel


    com.alibaba.cloud
    spring-cloud-starter-alibaba-sentinel

1. 下载控制台 jar包

https://github.com/alibaba/Sentinel/releases  下载控制台 jar 包。此处下载的是1.8.5

2.启动控制台

Sentinel 控制台是一个标准的 Spring Boot 应用,以 Spring Boot 的方式运行 jar 包即可。

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.5.jar

注意:下载的版本的区别,不都是1.8.5

启动之后访问ip:8080

SpringCloudAlibaba之Sentinel(一)流控篇_第2张图片

 user/pwd sentinel/sentinel

在代码端(客户端):

pom中:

        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-sentinel
        
    

 之后在application.yml文件中:主要是:spring.cloud.sentinel.transport.dashboard

server:
  port: 8087
spring:
  application:
    name: order_nacos-sentinel
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        username: nacos
        password: nacos
        namespace: public
    sentinel:
      transport:
        dashboard: localhost:8080

SpringCloudAlibaba之Sentinel(一)流控篇_第3张图片

我们写的服务需要访问一次才能在dashboard中显示

访问了下列地址每个地址一次之后:

http://192.168.50.59:8087/order/getStock

http://192.168.50.59:8087/order/test1

http://192.168.50.59:8087/order/test2

http://192.168.50.59:8087/order/flow

之后,就可以发现:

SpringCloudAlibaba之Sentinel(一)流控篇_第4张图片

3.流控(直接流控)

  (1) QPS流控

给getStock设置一个QPS流控:

SpringCloudAlibaba之Sentinel(一)流控篇_第5张图片

 设置为1

我们继续访问http://192.168.50.59:8087/order/getStock,连续多点,会出现以下:

SpringCloudAlibaba之Sentinel(一)流控篇_第6张图片

 怎么改这个页面呢?

指定的blockHandler方法要求:

1.必须是public的  2.方法返回值必须和源方法相同 3.方法参数和源方法相同,最后一个方法参数是BlockException

SpringCloudAlibaba之Sentinel(一)流控篇_第7张图片

 继续快速访问

SpringCloudAlibaba之Sentinel(一)流控篇_第8张图片

 这里出现了一个问题:我的程序每次重新启动的时候,流控规则都消失了,因为现在这些规则是存放在内存中的,没有做持久化

(2)线程数流控

也可以说是并发线程数流控

线程数流控和QPS流控有什么区别呢?

以一个为例:

qps为1的话代表每秒只允许有一个请求访问,

并发线程数为1的话,只要有一个线程访问,这个线程没有访问结束,那么其他线程就不能再次访问,测试的时候用睡眠的方式来测试。

@RequestMapping("/flow")
    @SentinelResource(value = "getStock",blockHandler = "flowBlockException")
    public String flow(){
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return "QPS流控";
    }

    public String flowBlockException(BlockException e){
        return "并发线程数流控";
    }

 SpringCloudAlibaba之Sentinel(一)流控篇_第9张图片

SpringCloudAlibaba之Sentinel(一)流控篇_第10张图片

 如果不想用@SentinelResource

那么我们可以写一个类:实现:BlockExceptionHandler

SpringCloudAlibaba之Sentinel(一)流控篇_第11张图片

@Component
@Slf4j
public class MyBlockException implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest
            , HttpServletResponse httpServletResponse, BlockException e) throws Exception {

        if(e instanceof BlockException){
            log.error("被流控了" + e.getRule());
        }else if(e instanceof DegradeException){
            log.error("被降级了" + e.getRule());
        }
        httpServletResponse.getWriter().print(e.getRule());

//        new ObjectMapper().writeValue(httpServletResponse.getWriter(),e.getRule());
    }

流控规则一般在服务的提供方,降级规则设置在服务的消费端。

4.关联流控

SpringCloudAlibaba之Sentinel(一)流控篇_第12张图片

 当关联资源1被设置了以后限流以后,限制的不是自己,而是资源2的流控

这里会用到Jmeter这个测试工具,关于JMeter中文的设置(使用之前一定要配置好jdk)

性能测试(2): 测试工具 -- JMeter 安装和中文设置-腾讯云开发者社区-腾讯云

这里多写了一个简单的/add接口

SpringCloudAlibaba之Sentinel(一)流控篇_第13张图片

SpringCloudAlibaba之Sentinel(一)流控篇_第14张图片

 启动测试计划以后访问:http://127.0.0.1:8087/order/getStock

访问不了,显示被流控了

5.链路流控

   想要使用这个功能,配置文件中,必须设置:spring.cloud.sentinel.web-context-unify 这个属性值默认为true,表示收敛调用链路的。

spring.cloud.sentinel.web-context-unify=false

SpringCloudAlibaba之Sentinel(一)流控篇_第15张图片

 要说明的是:进行流控的资源名不一定是controller中的接口,也有可能是service中的方法

controller中:

SpringCloudAlibaba之Sentinel(一)流控篇_第16张图片

 service中:


@Service
@Slf4j
public class OrderService {

    @SentinelResource(value = "aa",blockHandler = "aaBlockException")
    public String aa(){
        log.info("测试链路流控...");
        System.out.println("测试链路流控...");
        return "测试链路流控...";
    }

    public String aaBlockException(BlockException e){
        log.error(e.getRule()+" ~~~");
        return "wawawawawwwawa";
    }
}

 SpringCloudAlibaba之Sentinel(一)流控篇_第17张图片

 测试的过程中会发现test3接口怎么测试都不会发生变化,test4访问速度过快就会显示wawawawawwwawa

6.流量效果

1.快速失败

2.warm up 预热

    针对激增流量突然涌入进来打垮冷系统,防止缓存击穿。刚开始QPS是(阈值/3) ,经过填写的预热时间增长到阈值

Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量 突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐 增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。 冷加载因子: codeFactor 默认是3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。

3.排队等待

    针对脉冲流量

 这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下 来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的 请求。

SpringCloudAlibaba之Sentinel(一)流控篇_第18张图片

 

你可能感兴趣的:(sentinel)