SpringCloudAlibaba之Sentinel(一)流控篇

前言:

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

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

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

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

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

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

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

限制流量

熔断

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

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

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

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

1. 下载控制台 jar包

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

2.启动控制台

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

bash 复制代码
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

user/pwd sentinel/sentinel

在代码端(客户端):

pom中:

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

之后在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

我们写的服务需要访问一次才能在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

之后,就可以发现:

3.流控(直接流控)

(1) QPS流控

给getStock设置一个QPS流控:

设置为1

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

怎么改这个页面呢?

指定的blockHandler方法要求:

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

继续快速访问

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

(2)线程数流控

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

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

以一个为例:

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

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

java 复制代码
@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 "并发线程数流控";
    }

如果不想用@SentinelResource

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

java 复制代码
@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.关联流控

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

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

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

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

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

访问不了,显示被流控了

5.链路流控

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

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

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

controller中:

service中:

java 复制代码
@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";
    }
}

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

6.流量效果

1.快速失败

2.warm up 预热

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

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

3.排队等待

针对脉冲流量

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

相关推荐
cui_win21 小时前
Redis高可用-Sentinel(哨兵)
redis·bootstrap·sentinel
FIN技术铺3 天前
Redis集群模式之Redis Sentinel vs. Redis Cluster
数据库·redis·sentinel
cyt涛4 天前
Sentinel — 微服务保护
微服务·架构·sentinel·限流·熔断·降级·隔离
ketil276 天前
Redis - 哨兵(Sentinel)
数据库·redis·sentinel
阿伟*rui7 天前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
茶馆大橘8 天前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel
Shenqi Lotus8 天前
Redis-“自动分片、一定程度的高可用性”(sharding水平拆分、failover故障转移)特性(Sentinel、Cluster)
redis·sentinel·cluster·failover·sharding·自动分片·水平拆分
Genius Kim8 天前
SpringCloud Sentinel 服务治理详解
spring cloud·sentinel·php
为美好的生活献上中指8 天前
Java学习Day60:微服务总结!(有经处无火,无火处无经)
java·spring boot·spring cloud·微服务·sentinel·jetty
转世成为计算机大神8 天前
易考八股文之谈谈对sentinel的理解和作用?
java·开发语言·sentinel