spring cloud sentinel实现熔断和限流

微服务容器数据库

picture.image

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

哨兵是什么?

  • 丰富的应用场景:Sentinel 近 10 年的双十一承接控制了阿里巴巴的大型促销活动,例如秒杀(即瞬间传输容量可以承受的范围)、消息削峰控制填谷、集群、实时熔断中断不能应用等。

  • 完整的实时监控系统提供了实时监控的情况。可以在台运行的实时监控设备中监测功能甚至应用程序的 500 台实时监控级别的数据。

  • 广泛的开源生态:Sentinel 提供开箱即用的与其他开源框架/的集成模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的集成。库只需要引入相应的依赖并进行简单的配置同时Sentinel提供Java/Go/C++等多种语言的惊艳实现。

  • 完善的 SPI 扩展机制:提供简单、易用的 SPI 扩展接口。您可以通过实现扩展接口来快速地自定义。定制规则管理、定制动态数据源等。

    Sentinel的主要特性

picture.image

Sentinel 的开源生态

picture.image

哨兵分为两个部分:

  • 核心库(Java客户端)不依赖任何环境框架,能够运行于所有Java运行时,同时对Dubbo/Spring Cloud等框架也有/的支持。

  • 内容(Dashboard)基于Spring Boot直接开发,打包后可以运行,不需要额外的Tomcat等应用。

    服务保护的相关概念

服务限流/熔断:在高并发情况下,客户端请求达到了一定的极限,也就是我们所设定的阈值,服务就会自动开启自我保护机制,直接走我们的服务降级fallback方法,给客户端一个友好提示。

服务降级:在高并发情况下,为了防止用户一直等待,给用户一个友好提示。

服务的雪崩效应:默认情况下,tomcat/jetty服务器只有一个线程池去处理用户请求。在高并发情况下,如果客户端的所有请求都堆积在同一个接口上,线程池中的所有线程都用来处理这些请求,就会导致其他接口无法访问。

服务隔离机制:服务隔离机制分为两种:信号量隔离和线程池隔离。信号量隔离:最多只能有一定的阈值的线程数来处理我们的请求,超过阈值就会拒绝请求。线程池隔离:每个服务接口都有独立的线程池来处理请求,接口之间互不影响,缺点:占用CPU资源较大。

Sentinel和Hytrix区别

SentinelHytrix
隔离策略信号量隔离线程池隔离/信号量隔离
熔断降级策略基于响应时间或失败比率基于失败比率
实时指标实现滑动窗口滑动窗口(基于RxJava)
规则配置支持多种数据源支持多种数据源
扩展性多个扩展点插件的形式
基于注解的支持支持支持
限流基于QPS,支持基于调用关系的限流不支持
流量整形支持慢启动、匀速器模式不支持
系统负载支持支持不支持
控制台开箱即用,可配置规则、查看秒级监控、机器发现等不完善
常见框架适配servlet、spring cloud、Dobbo、gRpc等servlet、spring cloud netflix

sentinel官方中文文档地址

  
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

spring cloud sentinel实战

安装sentinel** 控制台**

Sentinel 控制台是流量控制、熔断降级规则统一配置和管理的入口,它为用户提供了机器自发现、簇点链路自发现、监控、规则配置等功能。在 Sentinel 控制台上,我们可以配置规则并实时查看流量控制效果。

sentinel控制台安装可以查看官方文档来,文档地址:

  
https://github.com/alibaba/Sentinel/tree/master/sentinel-dashboard

picture.image

  
wget https://github.com/alibaba/Sentinel/releases/download/1.8.3/sentinel-dashboard-1.8.3.jar  
java -Dserver.port=8999 -Dcsp.sentinel.dashboard.server=localhost:8999 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

-Dserver.port=8999和localhost:8999端口号要一模一样,localhost:就是服务所在地址用于指定 Sentinel 控制台端口为8080,默认用户名和密码都是sentinel,访问浏览器http://127.0.0.1:8999/

picture.image

上一篇spring cloud fegin服务调用实战与调优,在nacos-feign模块引入如下依赖

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

在application.yml或bootstrap.yml添加如下配置

  
spring:  
 application:  
 name: nacos-feign  
 cloud:  
 nacos:  
 server-addr: 192.168.1.10:8848  
 discovery:  
 namespace: 3dbbf06e-9ab7-49eb-b4ab-3118cfbf9dfd  
 username: nacos  
 password: nacos  
 service: ${spring.application.name}  
 group: DEFAULT_GROUP  
 sentinel:  
 transport:  
 port: 8719   
 dashboard: 127.0.0.1:8999

spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。

spring.cloud.sentinel.transport.dashboard控制台的服务地址

在接口方法添加@SentinelResource注解

  
package com.lmf.cloud.controller;  
  
import com.alibaba.csp.sentinel.annotation.SentinelResource;  
import com.lmf.cloud.service.TestService;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  
@RestController  
public class TestController {  
 @Autowired  
    TestService testService;  
 @GetMapping("/test")  
 //SentinelResource注解用来标识资源是否被限流、降级  
 @SentinelResource("/test")  
 public String test(){  
 String str=testService.test();  
 return str;  
 }  
}

@SentinelResource注解定义项资源,并提供可选的异常处理和回退配置, 不支持私人方法。

  
value:资源名称,必须项  
entryType:entry 类型,可选项(默认为EntryType.OUT)  
blockHandler/blockHandlerClass:blockHandler处理BlockException的函数名称,可选项。blockHandler 函数访问范围是public,返回类型需要与原匹配匹配,参数类型需要和原方法匹配并且最后添加一个额外的参数,类型为BlockException。blockHandler 函数默认需要如果希望使用其他类的函数,则指定blockHandlerClass为对应类的Class对象,否则必须是静态函数,否则无法解析。  
fallback/ fallbackClass:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对类型的异常(除了exceptionsToIgnore里面丢弃的异常类型)进行所有处理。fallback 函数签名和要求:  
返回值类型与原函数返回值类型必须一致;  
方法参数列表需要和原函数一致,或者可以额外使用一个Throwable类型的参数接收多个匹配项。  
如果希望使用其他类的函数,则可以指定fallbackClass为类的Class对象,注意函数必须为静态函数,否则无法解析。

属性值:fallback/fallbackClass 使用,业务方面的熔断降级

单个fallback熔断降级处理方法配置

  
 //SentinelResource注解用来标识资源是否被限流、降级  
 @SentinelResource(value = "test",fallback = "testcallback")  
 public String test(){  
 String str=testService.test();  
 return str;  
 }  
 public String testcallback(){  
 return "这是一个熔断降级的方法";  
 }

blockHandlerClass限流降级处理类配置

为了提高代码的可读性以及解耦,我们将自定义的熔断降级方法专门写入到一个熔断降级类中,需要时再进行调用。

  
 @GetMapping("/test2")  
 //SentinelResource注解用来标识资源是否被限流、降级  
 @SentinelResource(value = "test",fallbackClass = FallBack.class,fallback = "fallback")  
 public String test2(){  
 String str=testService.test();  
 return str;  
 }
  
package com.lmf.cloud.fallback;  
public class FallBack {  
 //如果希望使用其他类的函数,则可以指定fallbackClass为类的Class对象,  
 // 注意函数必须为静态函数,否则无法解析。  
 public static String fallback(){  
 return "这是熔断降级方法";  
 }  
}  

单个blockHandler限流降级处理方法配置,testblock和testHandler

  
 @GetMapping("/testblock")  
 //SentinelResource注解用来标识资源是否被限流、降级  
 @SentinelResource(value = "testblock",blockHandler ="testHandler" )  
 public String testblock(){  
 String str=testService.test();  
 return str;  
 }  
 public String testHandler(BlockException ex ){  
 //todo 做一些日志输出  
 return "这是限流方法";  
 }

picture.image

picture.image

如果请求超过1QPS就会自动限流

picture.image

blockHandlerClass限流降级处理类配置

为了提高代码的可读性以及解耦,我们将自定义的限流降级方法专门写入到一个限流降级类中,需要时再进行调用。

  
 @GetMapping("/testblock2")  
 //SentinelResource注解用来标识资源是否被限流、降级  
 @SentinelResource(value = "testblock2",blockHandlerClass = BlockHandlers.class,blockHandler = "blockHandler")  
 public String testblock2(){  
 String str=testService.test();  
 return str;  
    }
  
package com.lmf.cloud.blockHandlers;  
import com.alibaba.csp.sentinel.slots.block.BlockException;  
public class BlockHandlers {  
 public static String blockHandler(BlockException ex){  
 return "这是限流方法";  
 }  
}  

picture.image

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
云原生可观测性技术的落地实践
云原生技术和理念在近几年成为了备受关注的话题。应用通过云原生改造,变得更动态、弹性,可以更好地利用云的弹性能力。但是动态、弹性的环境也给应用以及基础设施的观测带来了更大的挑战。本次分享主要介绍了云原生社区中可观测性相关的技术和工具,以及如何使用这些工具来完成对云原生环境的观测。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论