厦门市建设工程造价网站首页,本地网站建设软件,完整的网络营销推广方案包括,免费发布推广平台【Springcloud】Sentinel熔断和降级 【一】基本介绍【1】什么是熔断和降级【2】为什么使用熔断和降级【3】Sentinel熔断和降级【4】核心概念 【二】下载方式【1】Windows平台安装包下载【2】打开控制台 【三】使用案例【1】添加依赖【2】添加Sentinel配置【3】添加TestUserCont… 【Springcloud】Sentinel熔断和降级 【一】基本介绍【1】什么是熔断和降级【2】为什么使用熔断和降级【3】Sentinel熔断和降级【4】核心概念 【二】下载方式【1】Windows平台安装包下载【2】打开控制台 【三】使用案例【1】添加依赖【2】添加Sentinel配置【3】添加TestUserController.java模拟接口返回用户信息。【4】启动服务 【四】定义资源【1】代码定义【2】属性说明 【五】流量规则【1】控制台定义【2】代码定义【3】属性说明 【五】降级规则【1】控制台定义【2】代码定义【3】属性说明 【五】动态配置规则【1】文件配置规则【2】Nacos配置规则 【六】RestTemplate 支持【七】RestTemplate 支持【1】添加依赖【2】feign开启sentinel支持【3】测试用户服务类RemoteUserService.java【4】降级用户服务类处理RemoteUserFallbackFactory.java【5】启动类扫描配置 【一】基本介绍
【1】什么是熔断和降级
服务的稳定是公司可持续发展的重要基石随着业务量的快速发展一些平时正常运行的服务会出现各种突发状况而且在分布式系统中每个服务本身又存在很多不可控的因素比如线程池处理缓慢导致请求超时资源不足导致请求被拒绝又甚至直接服务不可用、宕机、数据库挂了、缓存挂了、消息系统挂了…对于一些非核心服务如果出现大量的异常可以通过技术手段对服务进行降级并提供有损服务保证服务的柔性可用避免引起雪崩效应。
1服务熔断 一般是指软件系统中由于某些原因使得服务出现了过载现象为防止造成整个系统故障从而采用的一种保护措施。
2服务降级 是在服务器压力陡增的情况下利用有限资源根据当前业务情况关闭某些服务接口或者页面以此释放服务器资源以保证核心任务的正常运行。
【2】为什么使用熔断和降级
在一个分布式系统里一个服务依赖多个服务可能存在某个服务调用失败比如超时、异常等需要保证在一个依赖出问题的情况下不会导致整体服务失败。
【3】Sentinel熔断和降级
随着微服务的流行服务和服务之间的稳定性变得越来越重要。Sentinel是面向分布式服务架构的流量控制组件主要以流量为切入点从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。
sentinel具有以下特征 1丰富的应用场景 Sentinel承接了阿里巴巴近十年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围),消息削峰填谷,集群流量控制,实时熔断下游不可用应用等
2完美的实时监控 Sentinel同时提供实时的监控功能,您可以在控制台看到接入应用的单台机器秒级数据,甚至500台一下规模的集群的汇总运行情况
3广泛的开源生态 Sentinel提供开箱即用的与其他框架/库的整合模块,例如与SpringCloud,Dubbo,gRPC的整合,您只需要引入响应的依赖并进行简单的配置即可快速接入Sentinel
4完美的SPI扩展点 Sentinel提供简单易用的,完美的SPI扩展接口,可以通过实现扩展接口来快速定制逻辑,例如定制规则管理,适配动态数据源等
【4】核心概念
1核心库 不依赖任何框架/库能够允许在jdk7以上的版本运行时环境同时对Dubbo、SpringCloud等框架也有比较好的支持。
2控制台 主要负责管理推送规则、监控、集群限流分配管理、机器发现等。
【二】下载方式
注意启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
【1】Windows平台安装包下载
可以从https://github.com/alibaba/Sentinel/releases下载sentinel-dashboard-$version.jar包。
使用如下命令启动控制台
java -Dserver.port8718 -Dcsp.sentinel.dashboard.serverlocalhost:8718 -Dproject.namesentinel-dashboard -Dcsp.sentinel.api.port8719 -jar D:\sentinel\sentinel-dashboard-1.8.0.jar其中-Dserver.port8718用于指定Sentinel控制台端口为8718F:\software\sentinel\sentinel-dashboard-1.8.0.jar为下载的包路径地址。
如果觉得官网下载慢可以使用我分享的网盘地址: https://pan.baidu.com/s/1E9J52g6uW_VFWY34fHL6zA 提取码: vneh
【2】打开控制台
Sentinel提供了一个可视化的操作平台安装好之后在浏览器中输入(http://localhost:8718 (opens new window))就可以访问了默认的用户名和密码都是sentinel我使用的是1.8.0版本
【三】使用案例
【1】添加依赖
!-- springcloud alibaba sentinel --
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId
/dependency!-- SpringBoot Web --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId
/dependency【2】添加Sentinel配置
spring: application:# 应用名称name: ruoyi-xxxx cloud:sentinel:# 取消控制台懒加载eager: truetransport:# 控制台地址dashboard: 127.0.0.1:8718【3】添加TestUserController.java模拟接口返回用户信息。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;RestController
public class TestUserController
{GetMapping(/user/info)public Object info(){return {\username\:\admin\,\password\:\admin123\};}
}【4】启动服务
查看Sentinel控制台的请求数据
【四】定义资源
资源是Sentinel中的核心概念之一。我们说的资源可以是任何东西服务服务里的方法甚至是一段代码。最常用的资源是我们代码中的Java方法。Sentinel提供了SentinelResource注解用于定义资源并提供了AspectJ的扩展用于自动定义资源、处理BlockException等。
【1】代码定义
SentinelResource用于定义资源并提供可选的异常处理和fallback配置项。
接口定义IUserService.java
/*** 用户接口* * author ruoyi*/
public interface IUserService
{public Object selectUserByName(String username);
}接口实现IUserServiceImpl.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;/*** 用户实现* * author ruoyi*/
Service
public class IUserServiceImpl implements IUserService
{Autowiredprivate RestTemplate restTemplate;Beanpublic RestTemplate restTemplate(){return new RestTemplate();}SentinelResource(value selectUserByName, blockHandler selectUserByNameBlockHandler, fallback selectUserByNameFallback)Overridepublic Object selectUserByName(String username){return restTemplate.getForObject(http://localhost:9201/user/info/ username, String.class);}// 服务流量控制处理参数最后多一个 BlockException其余与原函数一致。public Object selectUserByNameBlockHandler(String username, BlockException ex){System.out.println(selectUserByNameBlockHandler异常信息 ex.getMessage());return {\code\:\500\,\msg\: \ username 服务流量控制处理\};}// 服务熔断降级处理函数签名与原函数一致或加一个 Throwable 类型的参数public Object selectUserByNameFallback(String username, Throwable throwable){System.out.println(selectUserByNameFallback异常信息 throwable.getMessage());return {\code\:\500\,\msg\: \ username 服务熔断降级处理\};}}测试接口请求TestUserController.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;RestController
public class TestUserController
{Autowiredprivate IUserService userService;GetMapping(/info/{username})public Object info(PathVariable(username) String username){return userService.selectUserByName(username);}
}【2】属性说明
SentinelResource注解包含以下属性
value资源名称必需项不能为空 entryType资源调用方向可选项默认为EntryType.OUT resourceType资源的分类 blockHandler对应处理BlockException的函数名称 blockHandlerClass处理类的Class对象函数必需为static函数 fallback用于在抛出异常的时候提供fallback处理逻辑 defaultFallback用作默认的回退的方法 fallbackClass异常类的Class对象函数必需为static函数 exceptionsToTrace异常类跟踪列表默认为Throwable.class exceptionsToIgnore排除掉的异常类型
注意注解方式埋点不支持 private 方法。
【五】流量规则
【1】控制台定义
选择流控规则新增流控规则填入对应信息
1资源名 唯一名称默认请求路径 2针对来源 Sentinel可以针对调用者进行限流填写微服务名默认default不区分来源 3阈值类型/单机阈值 1-QPS每秒请求数量当调用该api的QPS达到阈值的时候进行限流 2-线程数当调用该api的线程数达到阈值的时候进行限流 4是否集群 不需要集群 5流控模式 1-直接api达到限流条件时直接限流 2-关联当关联的资源达到限流阈值时就限流自己 3-链路只记录指定链路上的流量指定资源从入口资源进来的流量如果达到峰值就进行限流【api级别的针对来源】 6流控效果 1-快速失败直接失败抛异常 2-Warm Up根据coldFactor冷加载因子默认3的值从阈值/coldFactor经过预热时长才达到设置的QPS阈值 3-排队等待匀速排队让请求以匀速通过阈值类型必须设置为QPS否则无效
【2】代码定义
理解上面规则的定义之后我们可以通过调用FlowRuleManager.loadRules()方法来用硬编码的方式定义流量控制规则比如
private void initFlowQpsRule() {ListFlowRule rules new ArrayList();FlowRule rule new FlowRule(resourceName);// set limit qps to 20rule.setCount(20);rule.setGrade(RuleConstant.FLOW_GRADE_QPS);rule.setLimitApp(default);rules.add(rule);FlowRuleManager.loadRules(rules);
}【3】属性说明
流量控制规则FlowRule重要属性
resource资源名资源名是限流规则的作用对象 limitApp流控针对的调用来源若为 default 则不区分调用来源 default代表不区分调用来源 grade限流阈值类型QPS 模式1或并发线程数模式0 QPS 模式 count限流阈值 strategy调用关系限流策略直接、链路、关联 根据资源本身直接 controlBehavior流量控制效果(直接拒绝、Warm Up、匀速排队) 直接拒绝 clusterMode是否集群限流 否
同一个资源可以同时有多个限流规则检查规则时会依次检查。
从1.6.3版本开始Sentinel Web filter默认收敛所有URL的入口context因此链路限流不生效。1.7.0版本开始对应SCA 2.1.1.RELEASE)我们在CommonFilter引入了WEB_CONTEXT_UNIFY这个init parameter用于控制是否收敛context。将其配置为false即可根据不同的URL进行链路限流。 参考https://github.com/alibaba/sentinel/issues/1213
【五】降级规则
现代微服务架构都是分布式的由非常多的服务组成。不同服务之间相互调用组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定就可能会层层级联最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级暂时切断不稳定调用避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段通常在客户端调用端进行配置。
【1】控制台定义
选择降级规则新增降级规则填入对应信息。 【2】代码定义
private void initDegradeRule() {ListDegradeRule rules new ArrayList();DegradeRule rule new DegradeRule();rule.setResource(KEY);// set threshold RT, 10 msrule.setCount(10);rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);rule.setTimeWindow(10);rules.add(rule);DegradeRuleManager.loadRules(rules);
}【3】属性说明
熔断降级规则(DegradeRule)重要属性
resource资源名即规则的作用对象 grade熔断策略支持慢调用比例/异常比例/异常数策略 慢调用比例 count慢调用比例模式下为慢调用临界 RT超出该值计为慢调用异常比例/异常数模式下为对应的阈值 timeWindow熔断时长单位为 s minRequestAmount熔断触发的最小请求数请求数小于该值时即使异常比率超出阈值也不会熔断1.7.0 引入 5 statIntervalMs统计时长单位为 ms如 60*1000 代表分钟级1.8.0 引入 1000 ms slowRatioThreshold慢调用比例阈值仅慢调用比例模式有效1.8.0 引入
同一个资源可以同时有多个降级规则。
【五】动态配置规则
上面的规则配置都是存在内存中的。即如果应用重启这个规则就会失效可以整合动态配置系统如ZooKeeper、Nacos、Apollo等动态地实时刷新配置规则。
【1】文件配置规则
Sentinel支持通过本地文件加载规则配置使用方式如下限流规则作为演示
spring:cloud:sentinel:datasource:ds1:file:file: classpath:flowRule.jsondata-type: jsonrule-type: flowflowRule.json对应com.alibaba.csp.sentinel.slots.block.flow.FlowRule各属性。
[{resource: selectUserByName,count: 1,grade: 1,limitApp: default,strategy: 0,controlBehavior: 0}
]【2】Nacos配置规则
当sentinel重新启动时sentinel dashboard中原来的数据将会全部消失这样就需要重新定义限流规则无疑是不可取的。所以需要将sentinel中定义的限流规则保存到配置中心里面。
具体的实现方法如下 1在nacos中定义自定义限流策略sentinel-ruoyi-xxxx
[{resource: selectUserByName,count: 2,grade: 1,limitApp: default,strategy: 0,controlBehavior: 0}
]2添加依赖
!-- springcloud alibaba nacos config --
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactId
/dependency!-- sentinel datasource nacos --
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId
/dependency3添加相关配置sentinel下面的dataSource中配置nacos
spring: application:# 应用名称name: ruoyi-xxxx cloud:nacos:config:# 配置中心地址server-addr: 127.0.0.1:8848# 配置文件格式file-extension: yml# 共享配置shared-configs:- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}sentinel:# 取消控制台懒加载eager: truetransport:# 控制台地址dashboard: 127.0.0.1:8718# nacos配置持久化datasource:ds1:nacos:server-addr: 127.0.0.1:8848dataId: sentinel-ruoyi-gatewaygroupId: DEFAULT_GROUPdata-type: jsonrule-type: flow4启动sentinel应用可以看到我们在nacos中配置的限流规则
【六】RestTemplate 支持
Spring Cloud Alibaba Sentinel支持对RestTemplate调用的服务进行服务保护。需要在构造RestTemplate Bean时添加SentinelRestTemplate注解。
RestTemplate添加SentinelRestTemplate注解保护支持。
Bean
SentinelRestTemplate(blockHandler handleException, blockHandlerClass ExceptionUtil.class, fallback fallback, fallbackClass ExceptionUtil.class)
public RestTemplate restTemplate() {return new RestTemplate();
}服务熔断处理类ExceptionUtil.java必须使用静态方法。
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse;public class ExceptionUtil
{// 服务流量控制处理public static ClientHttpResponse handleException(HttpRequest request, byte[] body,ClientHttpRequestExecution execution, BlockException exception){exception.printStackTrace();return new SentinelClientHttpResponse({\code\:\500\,\msg\: \服务流量控制处理\});}// 服务熔断降级处理public static ClientHttpResponse fallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution,BlockException exception){exception.printStackTrace();return new SentinelClientHttpResponse({\code\:\500\,\msg\: \服务熔断降级处理\});}
}【七】RestTemplate 支持
其实不管是Hystrix还是Sentinel对于Feign的支持核心代码基本上是一致的只需要修改依赖和配置文件即可。
【1】添加依赖
!-- SpringCloud Alibaba Nacos --
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId
/dependency!-- spring cloud openfeign 依赖 --
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId
/dependency【2】feign开启sentinel支持
spring: cloud:nacos:discovery:# 服务注册地址server-addr: 127.0.0.1:8848feign:sentinel:enabled: true【3】测试用户服务类RemoteUserService.java
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;/*** 用户服务* * author ruoyi*/
FeignClient(contextId remoteUserService, value ruoyi-system, fallbackFactory RemoteUserFallbackFactory.class)
public interface RemoteUserService
{/*** 通过用户名查询用户信息** param username 用户名* return 结果*/GetMapping(value /user/info/{username})public Object getUserInfo(PathVariable(username) String username);
}【4】降级用户服务类处理RemoteUserFallbackFactory.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import feign.hystrix.FallbackFactory;/*** 用户服务降级处理* * author ruoyi*/
Component
public class RemoteUserFallbackFactory implements FallbackFactoryRemoteUserService
{private static final Logger log LoggerFactory.getLogger(RemoteUserFallbackFactory.class);Overridepublic RemoteUserService create(Throwable throwable){log.error(用户服务调用失败:{}, throwable.getMessage());return new RemoteUserService(){Overridepublic Object getUserInfo(String username){return {\code\:\500\,\msg\: \用户服务熔断降级处理\};}};}
}【5】启动类扫描配置
EnableFeignClients(basePackages com.ruoyi)创建的类需要在resources\META-INF下的spring.factories配置加载自动装配类
org.springframework.boot.autoconfigure.EnableAutoConfiguration\.....com.ruoyi.system.api.factory.RemoteUserFallbackFactory