SpringCloudAlibaba 限流熔断--Sentinel

Sentinel的安装


1、下载使用

sentinel官网

下载sentinel地址:https://github.com/alibaba/Sentinel/releases

下载 sentinel-dashboard-1.7.2.jar


 通过java -jar启动sentinel ,默认sentinel占用的端口是8080 --server.port=8888是将端口设置为8888,如果有改端口需求则更改对应端口即可

1java  -jar .\sentinel-dashboard-1.7.2.jar --server.port=8888

用户和密码都是sentinel

2、maven方式

加入依赖管理和依赖

<dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>com.alibaba.cloud</groupId>

                <artifactId>spring-cloud-alibaba-dependencies</artifactId>

                <version>2.2.1.RELEASE</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>


<!--   spring-cloud-starter-alibaba-nacos-discovery  nacos服务注册中心   -->

<dependency>

    <groupId>com.alibaba.cloud</groupId>

    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>

</dependency>


<!-- spring-cloud-starter-alibaba-sentinel sentinel客户端-->

<dependency>

    <groupId>com.alibaba.cloud</groupId>

    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>

</dependency>


<!-- sentinel-datasource-nacos sentinel持久化数据 -->

<dependency>

    <groupId>com.alibaba.csp</groupId>

    <artifactId>sentinel-datasource-nacos</artifactId>

</dependency>

注意自己修改端口等对应的信息,在这里sentinel使用来自定义的8888端口

server:

  port: 8400

spring:

  application:

    name: sentinel-client  #应用名

  cloud:

    nacos:

      discovery: #服务注册中心地址

        server-addr: 127.0.0.1:8848

      config:  #nacos的配置中心地址,如果不需要用到则暂时注释掉

        server-addr: 127.0.0.1:8848

        file-extension: yml

    sentinel:

      transport:

        dashboard: 127.0.0.1:8888

        port: 8719

启动类

@SpringBootApplication

@EnableDiscoveryClient

publicclassSentinelClient8400 {

    publicstaticvoidmain(String[] args) {

        SpringApplication.run(SentinelClient8400.class, args);

    }

}

需要流控的Controller类,示例代码

importorg.springframework.web.bind.annotation.GetMapping;

importorg.springframework.web.bind.annotation.RestController;


@RestController

publicclassSentinelDemoController {


    @GetMapping("/test001")

    publicString test001(){

        return"test001";

    }


    @GetMapping("/test002")

    publicString test002() {

        return"test002";

    }


}

然后启动nacos,再启动sentinel jar包,然后再启动上面这个启动类

需要注意的是sentinel是懒加载的机制,也意味着需要访问一些上面Controller中的 /test001 才会在sentinel后台看到服务

浏览器访问一下 http://localhost:8400/test001

然后刷新一下sentinel后台 http://localhost:8080/#/dashboard/home

原文链接:https://blog.csdn.net/qq_41813208/article/details/106994203



使用方法

简介

Sentinel是面向分布式服务框架的轻量级流量控制框架,主要以流量为切入点,从流量控制,熔断降级,系统负载保护等多个维度来维护系统的稳定性。

在SpringCloud体系中,sentinel主要是为了替换原Hystrix的功能,与Hystrix相比,sentinel的隔离级别更加精细,提供的Dashboard可以在线更改限流熔断规则,而且使用也越加方便。要了解更多详细信息请移步至Sentinel官网

基础准备

要使用Sentinel提供的限流熔断能力,需要先做如下准备:

安装Sentinel

这部分内容我已经在第一期SpringCloud Alibaba微服务实战一 - 基础环境准备中提过,大家可以翻阅查看。

引入Sentinel

在需要配置限流熔断服务的POM文件中引入Sentinel组件

<!--Sentinel-->org.springframework.cloudspring-cloud-starter-alibaba-sentinel

自定义资源@SentinelResource

我们只需要在相关方法上加上@SentinelResource注解,让其可以成为sentinel识别的资源即可。如:

@GetMapping("/account/getByCode/{accountCode}")@SentinelResource(value = "getByCode")publicResultDatagetByCode(@PathVariable(value = "accountCode")String accountCode){    log.info("get account detail,accountCode is :{}",accountCode);    AccountDTO accountDTO = accountService.selectByCode(accountCode);returnResultData.success(accountDTO);}

在配置文件中添加sentinel的服务端地址

server:port:8010spring:application:name:account-servicecloud:nacos:discovery:server-addr:192.168.0.107:8848/sentinel:transport:# sentinel服务端地址dashboard:192.168.0.107:8858# 取消延迟加载eager:true

经过以上几步我们准备好了使用Sentinel的基础环境,接下来我们看看限流熔断的具体配置。

限流

概念说明

生产者accout-service是一个核心服务,我们通过压测得出服务的最大负载能力为60。如果某个时间account-service的请求数飙升达到了600,那服务肯定就直接gg了。所以为了保护我们的accout-service,我们会给它配置一个限流规则,如果每秒钟有超过60的请求那不好意思我直接丢掉不处理了,然后丢给消费者一个异常,想拖垮我,哼,没门!。

总而言之,限流是通过限制调用方对自己的调用,起到保护自己系统的效果。

限流配置

理想是丰满的,现实是骨感的。由于本人对Jmeter之类的压测工具不是很精通所以为了方便测试,我们就将accout-service的QPS单机阈值设置成5,如果每秒QPS超过5,直接丢弃。

这里的资源名就是我们使用@SentinelResource注解自定义的资源。

打开浏览器,快速刷新浏览器,当每秒请求书超过5时会看到如下错误:

在后端服务日志中你会看到如下的错误日志:

2019-12-1014:22:31,948ERROR[dispatcherServlet]:175- Servlet.service()forservlet[dispatcherServlet]incontext with path[]threw exception[Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException]with root causecom.alibaba.csp.sentinel.slots.block.flow.FlowException: null

不要慌,这说明我们的目的达到了,限流成功!

自定义异常

我们可以通过@SentinelResource中添加blockHandler参数,给其添加自定义异常方法。如:

@GetMapping("/account/getByCode/{accountCode}")@SentinelResource(value = "getByCode",blockHandler = "handleException")publicResultDatagetByCode(@PathVariable(value = "accountCode")String accountCode){    log.info("get account detail,accountCode is :{}",accountCode);    AccountDTO accountDTO = accountService.selectByCode(accountCode);returnResultData.success(accountDTO);}/**

* 自定义异常策略

* 返回值和参数要跟目标函数一样,参数可以追加BlockException

*/publicResultDatahandleException(String accountCode,BlockException exception){    log.info("flow exception{}",exception.getClass().getCanonicalName());returnResultData.fail(900,"达到阈值了,不要再访问了!");}

注意,自定义的异常方法的参数和返回值要跟目标方法一样,参数可以追加BlockException

效果如下:

比之前的那个错误页优雅多了有木有!

持久化配置

由于Sentinel的配置默认是放在内存中的,每当应用重启或者sentinel重启都会丢失数据,我们这里使用Nacos作为配置中心持久化限流配置。

修改pom文件,引入sentinel-datasource-nacos组件

com.alibaba.cspsentinel-datasource-nacos

修改application.yml,配置sentinel的数据源

spring:cloud:sentinel:datasource:ds:nacos:server-addr:10.0.10.48:8848data-id:${spring.application.name}-sentinelgroup-id:DEFAULT_GROUPrule-type:flow

在nacos中建立限流配置account-service-sentinel(配置格式设置成json)

[    {"resource":"getByCode","limitApp":"default","grade":1,"count":3,"strategy":0,"controlBehavior":0,"clusterMode":false}]

可以看到上面配置规则是一个数组类型,数组中的每个对象是针对每一个保护资源的配置对象,每个对象中的属性解释如下:

resource:资源名,即限流规则的作用对象

limitApp:流控针对的调用来源,若为 default 则不区分调用来源

grade:限流阈值类型(QPS 或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制

count:限流阈值

strategy:调用关系限流策略

controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)

clusterMode:是否为集群模式

进入sentinel查看dashboard,发现sentinel自动获取nacos的配置

频繁刷新浏览器调用接口,验证接口是否正常限流

熔断

概念说明

消费者order-service需要先调用product-service获取具体的product,然后再处理其他的业务逻辑。但是这个product-service接口不是很稳定,经常抛出异常;或者是响应缓慢,导致order-service的响应变慢;如果置之不理,order-service可能会被product-service拖垮。这时候为了保护order-service,我们需要对product-service接口进行熔断。

一言以蔽之:熔断是通过限制自己对外部系统的调用, 起到节约响应时间、维护链路稳定的作用。

熔断配置

Sentinel中的熔断降级有三个降级策略:

RT(平均响应时间):

当资源的平均响应时间超过阈值之后,资源进入准降级状态。接下来如果持续进入 5 个请求,它们的 RT 都持续超过这个阈值,那么在接下的时间窗口之内,对这个方法的调用都会自动抛出 DegradeException 异常。在下一个时间窗口到来时, 会接着再放入5个请求, 再重复上面的判断.

异常比例

当资源的每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态,即在接下的时间窗口之内,对这个方法的调用都会自动地抛出DegradeException异常。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

异常数

当资源近 1 分钟的异常数目超过阈值之后会进行熔断。

首先我们对原接口进行改造,让其直接抛出Runtimeexception:

@GetMapping("/product/getByCode/{productCode}")@SentinelResource(value = "/product/getByCode",fallback = "fallbackHandler")publicResultDatagetByCode(@PathVariableString productCode){    log.info("get product detail,productCode is :{}",productCode);    ProductDTO productDTO = productService.selectByCode(productCode);thrownewRuntimeException("error");//        return ResultData.success(productDTO);}

这里我们将product-service设置如下的熔断规则:

如果/product/getByCode的异常率超过50%,那么接下来2秒内直接触发熔断降级,默认情况会抛出DegradeException异常,如:

2019-12-1019:35:53,764ERROR[dispatcherServlet]:175- Servlet.service()forservlet[dispatcherServlet]incontext with path[]threw exception[Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException]with root causecom.alibaba.csp.sentinel.slots.block.degrade.DegradeException: null

自定义异常

自定义熔断异常跟限流异常类似,我们使用fallback属性指定自定义异常的方法,如:

@SentinelResource(value = "/product/getByCode",fallback = "fallbackHandler")publicResultDatagetByCode(@PathVariableString productCode){ ...}/**

* 自定义熔断异常

* 返回值和参数要跟目标函数一样

*/publicResultDatafallbackHandler(String productCode){returnResultData.fail(800,"服务被熔断了,不要调用!");}

注意,自定义的异常方法的参数和返回值要跟目标方法一样

效果如下:

持久化配置

引入sentinel-datasource-nacos组件,跟限流一样配置即可

修改application.yml,配置sentinel的数据源

spring:cloud:sentinel:datasource:ds:nacos:server-addr:192.168.0.106:8848data-id:${spring.application.name}-sentinel-degradegroup-id:DEFAULT_GROUPrule-type:degrade

在nacos中建立配置文件product-service-sentinel-degrade,做如下配置

[    {"resource":"/product/getByCode","count":0.5,"grade":1,"passCount":0,"timeWindow":2}]

可以看到上面配置规则是一个数组类型,数组中的每个对象是针对每一个保护资源的配置对象,每个对象中的属性解释如下:

resource:资源名,即降级规则的作用对象

count:阈值

grade:降级模式 0:RT 1:异常比例 2:异常数

timeWindow:时间窗口(单位秒)

进入sentinel查看dashboard,发现sentinel自动获取nacos的配置

血与泪

大家在使用sentinel过程中如果出现Failed to fetch metric from 的错误,具体表现如下:

Failedtofetchmetricfrom (ConnectionException:Connectionrefused:nofurther information)

这个时候你需要去检查下sentinel控制台的服务列表,确认是否跟你ip一致。(我之前是装过虚拟机,sentinel一直抓取的是我虚拟的ip,不知道为什么。。。)

如果发现监听的地址不对的话,可以在sentinel客户端配置中加入客户端ip配置

spring:cloud:sentinel:transport:client-ip:192.168.0.108

至此我们已经给我们的微服务加上了限流熔断保护,再也不用担心异常流量的冲击,下游系统不稳定导致自身服务不可用了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容