Spring Cloud Alibaba 实操 (六) Sentinel限流

简介: Sentinel限流

1.Sentinel和Hystrix

1.1.限流和熔断

限流 , 限制流量,这里的流量我们可以理解成请求数量,其实就是限制服务器的请求并发数量,为什么要这么做?如果不做限流,那么在大量并发请求下我们的服务器会慢慢的变慢然后顶不住压力而挂掉(类似堵车)。并不是说并发越大越好,有的时候我们的项目规模和业务决定了我们不需要那么大的并发性,当大量的并发请求访问到服务器时我们需要把部分请求拒绝在外,这个是流量限制 - 限流。

熔断机制在在《Spring Cloud 极简入门》中有详细的解释,熔断机制是对服务调用链路的保护机制,如果链路上的某个服务不可访问,调用超时,发生异常等,服务会进行发熔断,触发降级返回托底数据。简单理解就是当服务器不可访问,可以返回一些预先准备好的兜底数据给用户,比如友好的提示信息,不至于直接向客户抛出异常。

1.2.Hystrix的熔断和资源隔离

其实在《Spring Cloud 极简入门》中我们已经学习过Hystrix的熔断和资源隔离机制,它的资源隔离可以通过线程池隔离和信号量隔离两种方式来实现对流量的控制。Hystrix相比Sentinel来说它的线程池隔离(限流)会造成线程上下切换对资源的消耗比较大;Hystrix使用的信号量进行资源的隔离效果不错,但是无法对慢调用进行自动降级。

1.4.Sentinel介绍

Sentinel诞生于阿里巴巴,其主要目标是流量控制和服务熔断,2018年,Sentinel演变为一个开源项目现如今成为了Spring Cloud Alibaba的一个子项目。Sentinel是通过限制并发线程的数量(即信号隔离)来减少不稳定资源的影响,而不是使用线程池,省去了线程切换的性能开销。

当资源的响应时间变长时,线程将开始被占用。当线程数累积到一定数量时,新的传入请求将被拒绝。反之亦然,当资源恢复并变得稳定时,占用的线程也将被释放,新请求将被接受。

除了限制并发性外,Sentinel可以根据响应时间降级不稳定资源也是保证可靠性的有效方法。当资源的响应时间太大时,将在指定的时间窗口中拒绝所有对该资源的访问。-- 熔断机制

此外,Sentinel支持的熔断降级维度更多,可对多种指标进行流控、熔断,且提供了实时监控和控制面板,功能更为强大。

2.Sentinel限流实战

2.1.Sentinel Server服务端

Sentinel 提供了现成的服务端供我们使用,点我下载地址,下载之后通过命令行启动

java -jar -Dserver.port=1111 sentinel-dashboard-1.6.0.jar

访问:http://localhost:1111 进入控制台,使用 sentinel/sentinel登录。
image.png

注意:只有1.6.0及以上版本才有这个登录页面。默认用户名和密码都是sentinel。对于用户登录的相关配置可以在启动命令中增加下面的参数来进行配置:

  • -Dsentinel.dashboard.auth.username=sentinel: 用于指定控制台的登录用户名为 sentinel;
  • -Dsentinel.dashboard.auth.password=123456: 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为 sentinel
  • -Dserver.servlet.session.timeout=7200: 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;
  • -Dserver.port=1111:配置端口

主页面效果
image.png

2.2.Sentinel 客户端接入

1.导入依赖

修改用户服务 springcloudalibaba-user-server-1010 ,加入sentinel依赖

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

2.配置Sentinel

修改yml配置,添加senticel服务控制台地址

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:1111

3.资源限流

Sentinel为我们提供了 @SentinelResource 注解标记需要限流的资源。 修改UserController,代码如下:

    @GetMapping("/user/{id}")
    //限流降级
    @SentinelResource(value="user",blockHandler="exceptionHandler")
    public User getById(@PathVariable Long id){
   
   
        System.out.println(notify);

        return new User(id,"zs:"+id, "我是zs");
    }
      // 限流与阻塞处理 : 参数要和 被降级的方法参数一样
    public User exceptionHandler(@PathVariable Long id, BlockException ex) {
   
   
        ex.printStackTrace();
        System.out.println("限流了...");
        return new User(-1L,"限流了","限流了");
    }

提示:这里通过@SentinelResource的value属性为资源取名为 “user” ,后续我们可以根据该资源名来进行限流。

同时这里通过 blockHandler 属性我配置了一个限流降级方法,即当“user”资源触发限流了会调用blockHandler指向的降级方法返回拖地数据,不至于抛出默认的限流异常信息给客户端(一串英文用户也看不懂) ,需要注意的是:降级方法要和被限流的方法参数一致,然后加上 BlockException异常对象。

当然,也可以通过 blockHandlerClass 属性把降级方法写在一个专门的类中,如:

@SentinelResource(value="user",blockHandler="exceptionHandler"
,blockHandlerClass=ExceptionUtil.Class)

降级类

public final class ExceptionUtil {
   
   
    public static User exceptionHandler(Long id ,lockException ex) {
   
   
       //...
    }
}

2.3.Sentinel设置限流策略

启动应用 springcloudalibaba-user-server-1010 ,然后通过浏览器访问 http://localhost:1010/user/11 ,然后登录Sentinel控制台,在“实时监控”列表中可以看到资源的相关监控信息的
image.png

在“族点链路”列表中可以看到资源的调用链 ,并且可以通过“流控”按钮设置流控规则
image.png

也可以在“流量控制”菜单中我们可以针对资源进行限流规则的设置。如下:
image.png

这里我添加了一个流控规则,资源名对应客户端 @SentinelResource(value="user".. 注解的资源,通过QPS限流(每秒请求数量),阈值是 1 ,意思是“user”这个资源每秒只能有1个请求进来,多余的请求会触发限流,返回降级数据。

2.4.限流测试

通过浏览器频发访问 “user”资源,当QPS大于1就会触发限流,效果如下:
image.png

2.5.总结

在这里我们探讨了Sentinel流控的简单使用,使用QPS方式进行流控。Sentinel还提供了非常强大的流控模式,继续往后看...

3.Sentinel流控模式

3.1.直接

Sentinel默认的流控处理就是【直接->快速失败】,QPS达到阈值,当前资源直接失败。在流控规则中配置如下:
image.png

3.2.关联

关联的资源达到某个阈值,限流自己,如:限流的资源是/user/delete ,关联的资源是/user/list,当/user/list达到阈值,限流user/delete , 举例: 支付并发太高,可以限制下单的流量
image.png

3.3.链路

限流线路调用链路的入口,如 /user/list 资源中 调用了 /dept/list ,对/dept/list添加限流,当/dept/list达到阈值,其实限流的是/user/list,因为他是访问的入口
image.png

4.Sentinel流控效果

4.1.快速失败

快速失败:(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)是默认的流控方式,当流量达到阀值直接返回异常,QPS达到任何规则阈值后,后续请求就会立即拒绝,并抛出FlowException 异常。简单理解:并发太高,直接请求拒绝

4.2.Warm Up预热

Warm Up预热:(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,根据codeFactor(默认3)的值,从(阀值/codeFactor)为初始阀值,经过预热时长,才到达设置的QPS的阀值,即预热/冷启动方式。简单理解:慢慢的增大处理并发的能力
image.png

提示:初始的QPS阈值为 100 / 3 =33 ,10秒后 QPS阈值达到 100.

当系统长期并发不高,流量突然增加可能会直接把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值的上限,给系统一个预热的时间,避免冷系统被压垮。

4.3.排队等待

排队等待(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER),忽然增加的请求并发量达到了限流阈值后续请求会被决绝,有时候我们可能更希望后续的请求可以加入队列进行排队,慢慢执行,而不是直接拒绝请求,这种方式后严格控制请求通过的时间间隔,也即是让请求以均匀的速度通过,对应的是漏桶算法,这种方式主要用于处理间隔性突发的流量,例如消息队列。 简单理解:突发流量处理不过来,让请求排队。
image.png

提示:QPS阈值为100,超过的请求会排队,排队超时时间为 10S

4.4.总结

上面介绍了Sentinel的流控模式和效果,小伙伴可以执行根据图例进行配置。

5.热点限流

还有一种特殊的动态限流规则,用于限制动态的热点资源 , 比如对同一个用户的请求频率做限定,比如对参数进行限定,比如对参数的值做限定(比如对商品ID为1的资源做限流)。

5.1.参数限流

参数限流就是 对资源的参数进行限流,我们来编写一个方法,接受两个参数:p1,和p2并设置好限流降级。

//限流降级
@SentinelResource(value="/parameterLimit",blockHandler="parameterLimitHandler")
@GetMapping(value="/parameterLimit")
public String parameterLimit(@RequestParam("p1") String p1 ,@RequestParam("p2") String p2){
   
   
    return "parameterLimit方法调用成功...";
}
// 限流与阻塞处理
public String parameterLimitHandler(@RequestParam("p1") String p1 ,@RequestParam("p2") String p2,BlockException ex) {
   
   
    return "限流了...";
}

配置热点规则 , 对第一个参数限流 , 当第一个参数超过了1的QPS就熔断降级。
image.png

5.2.参数值限流

对某一个参数的值满足某种条件的时候就进行限流,如下配置
image.png

意思是第一个参数的值为 haha 的时候限流阈值为10 , 超过 QPS > 10的并发就限流。

举例:应用场景比如说商品名称为“华为p40”的商品并发特别高,我们可以针对参数商品名为“华为p40”的商品进行限流。

6.系统规则

6.1.配置全局限流规则

系统规则可以看做是总的限流策略,所有的只要都要受到系统规则的限制。
image.png

上面的意思是最大并发只能允许 10 个线程数,并且是作用于全局的。

7.Gateway使用Sentinel限流

Spring Cloud Gateway 作为微服务的网关,它是微服务的访问入口,当请求的流量洪峰到来我们可以在Gateway网关层通过Sentinel对请求进行流控,把好第一道关。

7.1.导入依赖

这里我们需要导入sentinel基础依赖和 sentinel-gateway 整合依赖

<!--    限流和gataway使用-->
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
 </dependency>
 <dependency>    
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
 </dependency>

7.1.配置Sentinel地址

修改yml配置,增加Sentinel服务地址

spring:
    cloud:
      sentinel:
          transport:
            dashboard: localhost:1111

7.2.配置限流规则

启动Gateway,登录sentinel控制台,对url资源进行流控限制,配置方式和前面的配置方式一样,童鞋们可以自己测试一下。

8.做个小结

我们看到,Sentinel有非常丰富的限流方式,比Hystrix更好用和强大,同学名需要自己动,根据上面的配置执行测试。

目录
相关文章
|
4月前
|
Java UED Sentinel
微服务守护神:Spring Cloud Sentinel,让你的系统在流量洪峰中稳如磐石!
【8月更文挑战第29天】Spring Cloud Sentinel结合了阿里巴巴Sentinel的流控、降级、熔断和热点规则等特性,为微服务架构下的应用提供了一套完整的流量控制解决方案。它能够有效应对突发流量,保护服务稳定性,避免雪崩效应,确保系统在高并发下健康运行。通过简单的配置和注解即可实现高效流量控制,适用于高并发场景、依赖服务不稳定及资源保护等多种情况,显著提升系统健壮性和用户体验。
97 1
|
3月前
|
Java 数据中心 Sentinel
spring boot sentinel 的使用
要实现Spring Boot集成Sentinel的熔断降级,需引入Sentinel依赖并配置Dashboard地址;使用`@SentinelResource`注解定义受保护资源及blockHandler处理降级逻辑;通过Sentinel Dashboard配置熔断规则,如异常比例或响应时间。启动应用后,测试熔断功能,确保Sentinel正常工作。建议动态调整规则以提升系统稳定性。
|
4月前
|
算法 Java UED
你的Spring Boot应用是否足够健壮?揭秘限流功能的实现秘诀
【8月更文挑战第29天】限流是保障服务稳定性的关键策略,通过限制单位时间内的请求数量防止服务过载。本文基于理论介绍,结合Spring Boot应用实例,展示了使用`@RateLimiter`注解和集成`Resilience4j`库实现限流的方法。无论采用哪种方式,都能有效控制请求速率,增强应用的健壮性和用户体验。通过这些示例,读者可以灵活选择适合自身需求的限流方案。
144 2
|
4月前
|
算法 NoSQL Java
spring cloud的限流算法有哪些?
【8月更文挑战第18天】spring cloud的限流算法有哪些?
101 3
|
5月前
|
Java Sentinel Spring
spring boot 整合 sentinel
spring boot 整合 sentinel
64 1
|
5月前
|
算法 Java 数据库连接
Spring Boot中的限流策略实现
Spring Boot中的限流策略实现
|
6月前
|
Java 开发者 Sentinel
Spring Cloud系列——使用Sentinel进行微服务保护
Spring Cloud系列——使用Sentinel进行微服务保护
76 5
|
5月前
|
分布式计算 Java MaxCompute
详解 Java 限流接口实现问题之在Spring框架中使用AOP来实现基于注解的限流问题如何解决
详解 Java 限流接口实现问题之在Spring框架中使用AOP来实现基于注解的限流问题如何解决
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
224 2
|
4天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
42 14
下一篇
DataWorks