阅读本文大概需要20分钟,但是还是要动手实验的哈,实践是检验真理的唯一标准。感觉博主整理的不错的可以给个关注,本号后续陆续推出干货
流量控制&熔断降级产品对比
Sentinel | Hystrix | Resilience4j | |
---|---|---|---|
隔离策略 | 信号量隔离(并发线程数隔离) | 线程池隔离/信号量隔离 | 信号量隔离 |
熔断降级策略 | 基于响应时间、异常比率、异常数 | 基于异常比率 | 基于异常比率、响应时间 |
实时统计实现 | 滑动窗口 | 滑动窗口 | Ring Bit Bufffer |
动态规则配置 | 支持多种数据源 | 支持多种数据源 | 有限支持 |
扩展性 | 多个扩展点 | 插件的形式 | 接口的形式 |
基于注解的支持 | 支持 | 支持 | 支持 |
限流 | 基于QPS,支持基于调用关系的限流 | 有限的支持 | Rate Limiter |
流量整形 | 支持预热模式、匀速器模式、预热派对模式 | 不支持 | 简单的Rate Limiter |
系统自适应保护 | 支持 | 不支持 | 不支持 |
控制台 | 提供开箱即用的控制台、可配置规则、查看秒级监控、机器发现 | 简单的监控查看 |
Sentinel 介绍
Sentinel 概述
Sentinel是阿里巴巴出品的面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护等多个维度来保障微服务的稳定性
Sentinel 组成
-
核心库:主要是指Java客户端,不依赖任何框架、库,能够运行与java7及以上的版本运行时环境,同时对Dubbo、Spring Cloud等框架也有较好的支持 -
控制台:控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等
Sentinel 特性
Sentinel 相关概念
资源
资源是Sentinel的关键概念。它可以是Java应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。只要通过Sentinel API定义的代码,就是资源、能够被Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源
规则
规则指的是围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整
Sentinel 优势
-
友好的控制面板 -
支持实时监控 -
支持多种限流、支持QPS限流,线程数限流以及多种限流策略 -
支持多种降级模式、支持按平均返回时间降级,按多种异常数降级、按异常比率降级等 -
方便扩展开发,支持SPI模式对chain进行扩展 -
支持链路的关联、可以实现按照链路统计限流,系统保护,热门资源保护等
SpringBoot+Sentinel
SpringBoot 环境信息
-
SpringBoot 2.1.4.RELEASE -
JDK8 -
Sentinel 1.7.2
内置加载限流规则
-
pom加入sentinel依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.7.2</version>
</dependency> -
创建TestController
@RestController
public class TestController {
@GetMapping("/hello")
public String hello(){
// 限流的资源名称
try (Entry entry = SphU.entry("hello")){
return "hello sentinel";
}catch (BlockException e){
return "系统繁忙,请稍后";
}
}
@PostConstruct
public void initFlowRules(){
List<FlowRule> list = new LinkedList<>();
FlowRule rule = new FlowRule();
// 限流资源名称
rule.setResource("hello");
// 限流策略
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 限流数量定义QPS每秒能通过的请求个数
rule.setCount(2);
list.add(rule);
// 加载限流规则
FlowRuleManager.loadRules(list);
}
} -
此时启动应用,访问资源hello,每秒慢速点击访问可以正常访问,如果快速点击出现系统繁忙,请稍后
通过上面我们也能看到限流规则是在代码中写好的, 如果后续要修改的话,需要重新编译非常的麻烦,现在Sentinel提供了一个控制台,通过控制台我们就能动态的修改限流规则,现在我们看下怎么使用Sentinel控制台来实现限流策略
Sentinel 控制台启动
-
下载地址:https://github.com/alibaba/Sentinel/releases
-
启动
java -Dserver.port=8850 -jar sentinel-dashboard-1.8.4.jar
-
浏览器访问 localhost:8050 账号密码默认sentinel sentinel
SpringBoot应用与Sentinel控制台绑定
-
pom加入依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.7.2</version>
</dependency> -
JVM启动时添加参数
-Dcsp.sentinel.dashboard.server=localhost:8850
-Dproject.name=SentinelQuickStartDemo -
重启应用并通过浏览器访问 /hello接口几次,查看控制台中实时监控效果
-
动态设置限流规则
-
首先取消代码中的规则设置,注释掉规则代码
-
-
打开控制台设置限流规则
-
访问应用接口,查看限流规则是否生效
Sentinel 定义资源的方式
Sentinel除了基本的定义资源的方式外,还有其它的定义资源的方式,具体如下:
-
抛出异常的方式定义资源 -
返回布尔值的方式定义资源 -
异步调用支持 -
注解方式调用支持 -
主流框架的默认适配
抛出异常的方式定义资源
Sentinel中的SphU包含try-catch风格的api。用这种方式,当资源发生限流之后会抛出BlockException。这个时候可以捕捉异常,进行限流之后的逻辑处理,而我们在上面就使用了这种方式进行定义资源,关键代码如下:
// 使用限流规则监控保护资源
try (Entry entry = SphU.entry("hello")){
// 被保护的资源
return "hello sentinel";
}catch (BlockException e){
// 被限流或者降级的处理
return "系统繁忙,请稍后";
}
返回布尔值的方式定义资源
-
定义资源保护访问
@RestController
public class TestBooleanController {
@GetMapping("/boolean")
public boolean hello(){
if (SphO.entry("Sentinel_Boolean")){
try {
System.out.println("Hello Sentinel");
return true;
}finally {
SphO.exit();
}
}else{
// 限流降级的处理
System.out.println("系统繁忙,请稍后");
return false;
}
}
} -
新增限流规则
-
查看访问结果
异步调用支持方式
-
开启异步支持
// @EnableAsync 开启异步支持
@EnableAsync
@SpringBootApplication
public class SentinelApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelApplication.class, args);
}
} -
添加异步访问方法
新建AcyncService方法
@Service
public class AsyncService {
@Async
public void hello(){
System.out.println("异步开始======");
try {
Thread.sleep(5000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("异步结束======");
}
} -
添加异步访问资源
@RestController
public class TestAsyncController {
@Autowired
AsyncService asyncService;
@GetMapping("/async")
public void hello(){
AsyncEntry asyncEntry = null;
try {
asyncEntry = SphU.asyncEntry("Sentinel_Async");
asyncService.hello();
}catch (BlockException e){
System.out.println("系统繁忙,请稍后");
}finally {
if (asyncEntry != null ){
asyncEntry.exit();
}
}
}
} -
添加限流规则
-
查看访问效果
注解方式调用支持
-
添加注解支持的依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.7.2</version>
</dependency> -
创建Aspect配置类
@Configuration
public class AspectConfig {
@Bean
public SentinelResourceAspect sentinelResourceAspect(){
return new SentinelResourceAspect();
}
} -
创建限流访问资源代码
@RestController
public class TestAnnController {
@Autowired
AsyncService asyncService;
@SentinelResource(value = "Sentinel_Ann",blockHandler = "exceptionHandler")
@GetMapping("/ann")
public String hello(){
return "Hello Sentinel";
}
public void exceptionHandler(BlockException e){
e.printStackTrace();
System.out.println("系统繁忙,请稍后");
}
}
主流框架的默认适配
为了减少开发的复杂程度,对大部分的主流框架,例如Web Servlet,Dubbo、Spring Cloud、gRPC、Spring WebFlx、Reactor等都做了适配,只需要引入对应的依赖就可以方便的整合Sentinel
SpringCloud+Sentinel
下面是整理本文时阅读的一些资料汇总,有兴趣的可以去看看
版本参考地址
步骤
-
springcloud 版本
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> -
pom 加入sentinel依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.0.RELEASE</version>
</dependency> -
创建限流资源代码
@RestController
public class TestController {
@SentinelResource(value = "Sentinel_SpringCloud",blockHandler = "exceptionHandler")
@GetMapping("/ann")
public String hello(){
return "hello sentinel";
}
public String exceptionHandler(BlockException e){
e.printStackTrace();
return "系统繁忙,请稍后";
}
} -
配置项目链接控制台
spring.application.name=SpringCloudSentinel
spring.cloud.sentinel.transport.dashboard=localhost:8850 -
创建限流规则
Sentinel+Feign
-
引入feign+sentinel的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>10.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency> -
定义服务提供类,ServiceProvider 中修改
@EnableDiscoveryClient
@SpringBootApplication
public class ServerProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ServerProviderApplication.class, args);
}
@Slf4j
@RestController
static class TestController {
@GetMapping("/hello/{str}")
public String hello(@PathVariable String str) {
log.info("invoked name = " + str);
return "hello " + str;
}
@GetMapping("/test")
public String test() {
return "hello sentinel";
}
}
} -
增加feign客户端的支持
@SpringBootApplication
// 开启feign-client
@EnableFeignClients
public class SentinelApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelApplication.class, args);
}
} -
定义远程调用接口
@FeignClient(value = "alibaba-nacos-discovery-server",fallback = FallBackService.class)
public interface FeignAgent {
@GetMapping("/test")
String hello();
} -
定义回调降级类
@Component
public class FallBackService implements FeignAgent {
@Override
public String hello() {
return "系统繁忙,请稍后";
}
} -
配置项目链接sentinel控制台,开始sentinel对feign的支持
spring.application.name=SpringCloudSentinel
spring.cloud.sentinel.transport.dashboard=localhost:8850
# feign-sentinel 支持
feign.sentinel.enabled=true -
启动注册中心nacos,服务提供者serviceProvider和sentinel客户端
-
定义限流规则,Sentinel和Feign整合时,限流规则的编写形式为:
http请求方式:协议://服务名/请求路径跟参数
例:GET:http://alibaba-nacos-discovery-server/test
Sentinel+SpringCloud Gateway
-
引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2.1.0.RELEASE</version>
</dependency> -
配置gateway信息,链接Sentinel控制台
spring:
application:
name: SpringCloudGateWay
cloud:
gateway:
routes:
# id: sentinel-feign-gateway 限流时route id使用这个
- id: sentinel-feign-gateway
uri: lb://SpringCloudSentinel:8002
predicates:
# Path=/feign/** 自定义API维度限流使用
- Path=/feign/**
nacos:
discovery:
server-addr: 127.0.0.1:8848
sentinel:
transport:
dashboard: 127.0.0.1:8850
server:
port: 8003 -
配置限流时返回内容
@Component
public class GatewayConfiguration {
@PostConstruct
public void doInit(){
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
return ServerResponse.status(200).syncBody("系统繁忙,请稍后");
}
});
}
} -
启用服务发现
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
限流规则配置
-
route id
-
自定义API维度
流量控制实现
Sentinel的所有规则都可以在内存态中动态的查询及修改,修改之后立即生效。同时Sentinel也提供API,选择定制自己的规则策略
Sentinel主要支持以下几种规则
-
流量控制规则 -
熔断降级规则 -
系统保护规则 -
来源访问控制规则 -
动态规则扩展
流量控制规则实现
流量控制(flow control),其原理是监控应用流量的QPS或并发线程数等指标,当达到制定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性
流量控制主要有两种方式
-
并发线程数:并发线程数限流用于保护业务线程数不被耗尽
-
QPS:当QPS超过某个阈值的时候,则采取措施进行流量控制
一条限流规则主要由下面几个元素组成,我们可以组成这些元素来实现不同的限流效果:
-
resource:资源名,即限流的对象
-
count:限流阈值
-
grade:限流阈值类型(QPS或并发线程数)
-
limitApp:流控针对的调用来源,若为default则不区分调用来源
-
strategy:调用关系限流策略
-
controBehavior:流量控制效果(直接拒绝,Warm Up,匀速排队)
-
直接拒绝(RuleConstant.CONTROL_BRHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求被立即拒绝,拒绝方式为抛出 FlowException
.这种方式适用与对系统处理能力确切已知的请求下,比如通过压测确定了系统的准确水位时 -
Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热,冷启动方式,当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过“冷启动”,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间。避免冷系统被压垮 -
排队等待(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法
同一个资源可以同时由多个限流规则,检查规则时会依次检查
-
熔断降级
熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自行熔断(默认行为是抛出DegradeException)
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名,即限流规则的对象 | |
count | 阈值 | |
grade | 熔断策略,支持秒级RT/秒级异常比例/分钟级异常数 | 秒级平均RT |
timeWindow | 降级的时间,单位为s | |
reSlowRequestAmount | RT模式下1秒内连续多少个请求的平均RT超出阈值方可触发熔断(1.7.0引入) | 5 |
minRequestAmount | 异常熔断的触发最小请求数,请求数小于该值时及时异常比率超出阈值也不会熔断(1.7.0引入) | 5 |
同一个资源可以有多个降级规则
熔断策略详解
-
平均响应时间(DEGRADE_GRADE_RT):当1s内连续进入N个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以ms为单位),那么接下来的时间(DegradeRule 中的timeWindow,以s为单位)之内,对这个方法的调用都会自动熔断 -
异常比例(DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量>=N(可配置),并且每秒异常总数占通过量的比值超过阈值(DegradeRule中的count)之后,资源进入降级状态,即在接下的时间(DegradeRule 中的timeWindow,以s为单位)之内,对这个方法调用都会自动的返回。异常比率的阈值范围时[0.0,1.0],代表0%-100% -
异常数(DEGRADE_GRADE_EXCEPTION_COUNT):当资源近一分钟的异常数目超过阈值之后就会进行熔断。注意由于统计时间时分钟级别的,若timeWindow小于60s,则结束熔断状态后仍可能再进入熔断状态
熔断降级设计理念
在限制的手段上,Sentinel和Hystrix采取完全不一样的方法
Hystrix通过线程池隔离的方式,来对依赖(在Sentinel的概念中对应资源)进行了隔离,这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本(过多的线程池导致线程数目过多)还需要预先给各个资源做线程池大小的分配
Sentinel对这个问题采取了两种手段
-
通过并发线程数进行限制
和资源池隔离的方法不同,Sentinel通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会导致线程数的逐步累积,当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝,堆积的线程完成任务后才开始继续接收请求
-
通过响应时间对资源进行降级
除了对并发线程数进行控制以外,Sentinel还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复
系统自适应保护实现
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的Load、CPU使用率、总体平均RT、入口QPS和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能的保持最大吞吐量的同时保证系统整体的稳定性
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效,入口流量指的是进入应用的流量(EntryType.IN),比如Web服务或者Dubbo服务端接收到的请求,都属于入口流量
系统规则支持一下的模式
-
Load自适应(仅对Linux/Unix-like机器生效):系统的load1作为启发指标,进行自适应系统保护,当系统load1超过设定的启发值,且系统当前的并发线程数超过估算的系统容量是才会触发系统保护(BBR阶段).系统容量由系统的 maxQps*minRt
估算得出,设定参考值一般是CPU cores * 2.5
-
CPU usage (1.5.0版本):当系统CPU使用率超过阈值即出发系统保护(取值范围0.0-1.0)比较灵敏 -
平均RT:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护 -
并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护 -
入口QPS:当单台机器上所有入口流量的QPS达到阈值即触发系统保护
重要的属性
Field | 说明 | 默认值 |
---|---|---|
highestSystemLoad | load1触发值,用于触发自适应控制阶段 | -1(不生效) |
avgRt | 所有入口流量的平均响应时间 | -1(不生效) |
maxThread | 入口l巨量的最大并发数 | -1(不生效) |
qps | 所有入口资源的QPS | -1(不生效) |
highestCpuUsage | 当前系统的CPU使用率(0.0-1.0) | -1(不生效) |
代码控制
@RestController
public class TestLoadController {
@SentinelResource(entryType = EntryType.IN)
@GetMapping("/rule")
public String hello(){
return "hello sentinel rule";
}
// @PostConstruct
// public void initDegradeRule(){
// List<SystemRule> rules = new LinkedList<>();
// SystemRule rule = new SystemRule();
// rule.setQps(2);
// rules.add(rule);
// SystemRuleManager.loadRules(rules);
// }
}
控制台配置
系统设置
授权控制
很多时候,我们需要根据调用来源来判断请求是否允许放行,这时候可以使用Sentinel的来源访问控制(黑白名单控制)的功能,来源访问控制根据资源的请求来源(origin)判断资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过
重要属性
-
resource: 资源名,即限流规则的对象 -
limitApp: 请求来源,对应的黑名单/白名单,多个用“,"分割 -
strategy:限制模式,AUTHORITY_WHITE为白名单模式,AYTHORITY_BLACK为黑名单模式,默认为白名单模式
代码配置
-
黑白名单配置
@RestController
public class WhiteBlackController {
@SentinelResource(value = "Sentinel_Rule",blockHandler = "exceptionHandler")
@GetMapping("/rule")
public String hello(){
return "hello sentinel rule";
}
public String exceptionHandler(BlockException e){
e.printStackTrace();
return "系统繁忙,请稍后";
}
@PostConstruct
public void initWhiteRules(){
List<AuthorityRule> rules = new LinkedList<>();
AuthorityRule rule = new AuthorityRule();
rule.setResource("Sentinel_Rule");
rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
rule.setLimitApp("192.168.168.168");
rules.add(rule);
AuthorityRuleManager.loadRules(rules);
}
@PostConstruct
public void initBlackRules(){
List<AuthorityRule> rules = new LinkedList<>();
AuthorityRule rule = new AuthorityRule();
rule.setResource("Sentinel_Rule");
rule.setStrategy(RuleConstant.AUTHORITY_BLACK);
rule.setLimitApp("127.0.0.1");
rules.add(rule);
AuthorityRuleManager.loadRules(rules);
}
}
-
获取IP配置
@Component
public class SentinelConfig {
@PostConstruct
public void init(){
WebCallbackManager.setRequestOriginParser(new RequestOriginParser() {
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
return httpServletRequest.getRemoteAddr();
}
});
}
}
动态规则设置
拉模式拓展
实现拉模式的数据源最简单的方式是继承AutoRefreshDataSource
抽象类,然后实现readSource()
方法,在该方法里从指定数据源读取字符串格式的配置数据。
推模式拓展
实现推模式的数据源最简单的方式是继承 AbstractDataSource
抽象类,在其构造方法中添加监听器,并实现 readSource()
从指定数据源读取字符串格式的配置数据。比如 基于 Nacos 的数据源。
推模式:使用Nacos配置规则
-
pom加入依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.7.1</version>
</dependency> -
动态配置规则
@Component
public class SentinelDataSourceConfig {
private static final String KEY = "TestResource";
// nacos server ip
private static final String remoteAddress = "localhost:8848";
// nacos group
private static final String groupId = "Sentinel_Demo";
// nacos dataId
private static final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";
// if change to true, should be config NACOS_NAMESPACE_ID
private static boolean isDemoNamespace = false;
// fill your namespace id,if you want to use namespace. for example: 0f5c7314-4983-4022-ad5a-347de1d1057d,you can get it on nacos's console
private static final String NACOS_NAMESPACE_ID = "${namespace}";
@PostConstruct
private static void loadRules() {
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
private static void loadMyNamespaceRules() {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, remoteAddress);
properties.put(PropertyKeyConst.NAMESPACE, NACOS_NAMESPACE_ID);
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(properties, groupId, dataId,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
} -
发送nacos配置,或者手动创建
public static void main(String[] args) throws Exception {
final String remoteAddress = "localhost:8848";
final String groupId = "Sentinel_Demo";
final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";
final String rule = "[\n"
+ " {\n"
+ " \"resource\": \"Sentinel_SpringCloud\",\n"
+ " \"controlBehavior\": 0,\n"
+ " \"count\": 5.0,\n"
+ " \"grade\": 1,\n"
+ " \"limitApp\": \"default\",\n"
+ " \"strategy\": 0\n"
+ " }\n"
+ "]";
ConfigService configService = NacosFactory.createConfigService(remoteAddress);
System.out.println(configService.publishConfig(dataId, groupId, rule));
}
行了,到这就结束了,本来打算简单整理一下,但是发现越整理越多,而且真的是没有试验一切都是刷流氓,快去写个demo体验下Sentinel的丝滑吧
本文由 mdnice 多平台发布