0


SpringCloud Alibaba五大组件之——Sentinel

SpringCloud Alibaba五大组件之——Sentinel(文末附有完整项目GitHub链接)

前言

前文,我们已经介绍了SpringCloud Alibaba五大组件中的两个:dubbo和nacos,文章连接:太细了有手就行,SpringCloud Alibaba+Nacos+Dubbo整合,有需要的可以去查阅。
ps:本文用到的项目demo也是基于这篇文章去扩展的,包括模块结构和版本依赖等等。

一、什么是Sentinel

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
  • 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 的主要特性:
在这里插入图片描述
上面内容都是引用于官网

二、Sentinel控制台

官方提供两种方式跑控制台,我建议没有特殊需求下,通通用第一种就行

1.下载jar包

打来Sentinel的官网:https://github.com/alibaba/Sentinel/releases,找到自己需要的版本下载,本文编写时最高版本是1.8.8,本文用的是1.8.6版本
在这里插入图片描述

版本问题作者这里再啰嗦一句,一定要选对,因为我这一系列文章,SpringCloud alibaba定的是2021.0.6.0,所以一切版本如下图来选,直接毕业版本。
在这里插入图片描述

2.自己打包

下载整个工程,用mvn clean package打成jar包

3.启动控制台

打开cmd,进入jar包的目录,执行一下代码:

java -Dserver.port=8180-Dcsp.sentinel.dashboard.server=localhost:8180-Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar

其中 -Dserver.port=8180 用于指定 Sentinel 控制台端口为 8180,默认8080
dashboard.server:网页的端口,客户端必须按指定的访问,也可以省略,默认是127.0.0.1:8080

4.浏览器访问

访问:http://localhost:8180,默认账户和密码都是sentinel
在这里插入图片描述
登录,显示这个界面则成功
在这里插入图片描述

三、项目中引入Sentinel

1.在api-service模块的pom文件引入依赖:

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

2.application.yml

修改配置文件,新加如下配置:

spring:cloud:sentinel:transport:port:8719dashboard: localhost:8180

此处的port,默认是8179,主要就是项目启动后,会自行启动一个HTTP server,通过这个端口和sentinel客户端进行交互,来传输数据。
dashboard: localhost:8180,这个要和上一步启动sentinel控制台时候的ip端口一致。

3.补充:jvm启动参数

只要你前面配置和项目都正确,这一步可以省略,但是如果你项目启动,sentinel控制台服务注册不上,你就jvm加入下面参数:

-Dcsp.sentinel.dashboard.server=127.0.0.1:8180

4.编写简单的测试程序

controller:

@RestController@RequestMapping("/testSentinel")publicclassSentinelController{@ResourceUserInfoService userInfoService;@RequestMapping("/one")publicvoidtestThree(){
        userInfoService.testSentinel();}}

service:

@ServicepublicclassUserInfoServiceImpl{@Override@SentinelResource(value ="testSentinel", blockHandler ="testBlockHandler", fallback ="testFallback")publicvoidtestSentinel(){System.out.println("testSentinel");//这行代码是为了测试报错熔断,如果只是流控测试,此行代码可以屏蔽//int a = 1/0;}publicvoidtestBlockHandler(BlockException ex){System.out.println("进入testBlockHandler");}publicvoidtestFallback(Throwable e){System.out.println("进入testFallback");
        e.printStackTrace();}}

浏览器访问一下接口
查看控制台,这里可以看到我们的测试接口,项目已经集成好了sentinel
在这里插入图片描述
PS:1.因为sentinel是懒加载,这里一定要浏览器随便访问一个接口,不然服务注册不上,也可以添加配置:spring.cloud.sentinel.eager:true实现服务器启动了自动心跳注册。
2.访问了要等个几秒钟,有延迟,刷新一下就能看到了。

5.@SentinelResource注解

常用的几个注解参数:

  • value:定义资源名
  • blockHandler:会在原方法被限流/降级/系统保护的时候调用,记得方法定义在同一个类中。
  • fallback: 会针对所有类型的异常,出现时调用
  • defaultFallback:全局默认出异常时候调用,定义了fallback,则此参数不生效

6.其他方式

当然除了注解之外,还提供了其他编码方式去控制一段代码或者一个方法的访问,比如最常见的SphU.entry,大家也可以去官网上查阅根据需求选择

try{// 资源名可使用任意有业务语义的字符串,注意数目不能太多(超过 1K),超出几千请作为参数传入而不要直接作为资源名// EntryType 代表流量类型(inbound/outbound),其中系统规则只对 IN 类型的埋点生效
  entry =SphU.entry("自定义资源名");// 被保护的业务逻辑// do something...}catch(BlockException ex){// 资源访问阻止,被限流或被降级// 进行相应的处理操作}catch(Exception ex){// 若需要配置降级规则,需要通过这种方式记录业务异常Tracer.traceEntry(ex, entry);}finally{// 务必保证 exit,务必保证每个 entry 与 exit 配对if(entry !=null){
    entry.exit();}}

四、规则讲解

这里会讲几个常用的配置,其余的配置大家可以去官方查看:sentinel官网,配置规则主要有两种方式,第一种是代码中硬编码,第二种是通过控制台配置的形式

1.代码中硬编码

先介绍下,java代码中的几个规则对象:

  • DegradeRule:熔断降级,主要是当一个接口不可访问后,进行的一系列操作,避免所有请求堵塞
  • AuthorityRule: 授权规则(来源访问),判断来源请求是否放行,常用的场景是黑白名单
  • FlowRule: 流量控制规则,监控QPS,避免系统被瞬时的流量高峰冲垮
  • ParamFlowRule: 热点参数限流,可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效
  • SystemRule:系统保护规则,当系统负载高于某个阈值,就禁止或者减少流量的进入;当 load 开始好转,则恢复流量的进入

当然还有网关控制和集群流量控制,这两者在代码中无法实现,只有通过控制台配置。
我们就拿熔断规则来举例,在service中,增加如下规则初始化方法:

@PostConstructpublicvoidinitRule(){//熔断规则: 5s内调用接口出现异常次数超过5的时候, 进行熔断List<DegradeRule> degradeRules =newArrayList<>();DegradeRule rule =newDegradeRule();
        rule.setResource("testSentinel");
        rule.setCount(5);//统计时长
        rule.setStatIntervalMs(5000);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);//熔断规则//熔断时长
        rule.setTimeWindow(10);
        degradeRules.add(rule);DegradeRuleManager.loadRules(degradeRules);}

大家可以在文末获取代码自行去测试。

2.控制台配置(生产环境中不推荐)

控制台中我们有两种方式去添加流控规则
第一种方式:

(1)左侧菜单栏添加

在这里插入图片描述
在这里插入图片描述
注意这里的资源名,和我们代码中的资源名要匹配,不然配置不会生效。

(2)簇点链路中添加

在这里插入图片描述
在这里插入图片描述
在链路中添加,可以保证我们的资源名是一定存在的,两种添加方式,你自己选择喜欢的。

3.为何不推荐控制台中添加

因为控制台中添加规则,会推送到项目的内存中,重启就没了,不能持久化,所以在生产环境中不推荐,总不能你每次重启项目都要单独配置一次。

五、生产环境下,规则集成Nacos

生产环境下,都用的Nacos统一管理规则,就是常说的push规则,通过Nacos推送到sentinel控制台,然后再更新到项目中。这样即使项目重启,只要Nacos还在,配置就是接近持久化的状态。

1.引入依赖

由于spring-cloud-starter-alibaba-sentinel 的Maven依赖并没有引入Nacos相关的,所以我们要单独引入依赖:

<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency>

2.Nacos中新增config

新增一个流量控制的config
在这里插入图片描述
选取json格式:

[{"resource":"testSentinel","limitApp":"default","grade":1,"count":2,"strategy":0,"controlBehavior":0,"clusterMode":false}]
  • resource:资源名,即限流规则的作用对象
  • limitApp:流控针对的调用来源,若为 default 则不区分调用来源
  • grade:限流阈值类型(QPS 或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制
  • count:限流阈值
  • strategy:调用关系限流策略
  • controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)
  • clusterMode:是否为集群模式

3.application.yml文件修改

在前面的基础上,新增datasource的配置:
注意,这里的nacos一定要和上一步新增的对应,

spring:cloud:sentinel:transport:port:8719dashboard: localhost:8180datasource:ds:nacos:server-addr: 172.16.72.132:8848data-id: sentinel-rule
            namespace: 76dae550-4133-44d8-b591-dc82f5f97b6e
            group-id: SENTINEL_PROVIDER_GROUP
            username: nacos
            password: nacos
            data-type: json
            rule-type: flow

由于spring.cloud.sentinel.datasource属性对应的是一个Map,所以它的需要自定义指定Map的KEY,下面的配置中ds就作为KEY,然后后面就可以配置不同的数据源

4.重启

重启后,查看sentinel控制台,可以看到我们在nacos定义的规则在这里插入图片描述
测试一下新加的流控规则,我们是定义的qps不超过2,超过的请求全部拒绝(默认),这里补充一下拒绝策略。

  • 快速失败:超过设置阈值的请求全部拒绝,请求失败
  • Warm Up :
  • 排队等待:

在这里插入图片描述
可以看到,标记1和标记2都能正常打印,当第三个请求来了的时候,“进入testFallback”就不打印了,转而进入了blockHandler方法,说明流控是生效了的。

六、结语

到这里,SpringCloud alibaba五大组件之一的流控熔断降级sentinel就讲解完了,欢迎大家评论区指点,后面还剩两个组件:分布式队列RocketMQ和分布式事务Seata,RocketMQ可能会找个时间再写一篇文章,但是Seata的话,如果项目比较庞大,加上事务会顶不住,qps明显降低很多,我一个阿里工作的朋友给我谈过,他们项目组的微服务,都是裸奔的没有用事务,所以这文章我再考虑出不出,其实本文项目中的一个分支seata,我是已经实现了整合的,但是感觉生产环境中又不试用,就没有发出来,后面看情况吧
附上项目GitHub链接:https://github.com/wangqing-github/DubboAndNacos/tree/sentinel,选取sentinel分支。


本文转载自: https://blog.csdn.net/StreamlineWq/article/details/142366048
版权归原作者 一颗知足的心 所有, 如有侵权,请联系我们删除。

“SpringCloud Alibaba五大组件之——Sentinel”的评论:

还没有评论