“我们推荐通过动态配置源的控制台来进行规则写入和推送,而不是通过 Sentinel 客户端直接写入到动态配置源中。”
前言
- 前面的例子虽然实现了可视化动态流控规则配置,即在
sentinel-dashboard
配置并实时监控。
- 但是这些规则没有持久化,而是存储在内存中,并且
sentinel-dashboard
配置的规则也是通过接口写入到客户端应用内存的,所以客户端重启后规则就没了。
- 由于所在项目主使用阿里系技术(
springcloud-alibaba
),并且重度使用 nacos
,所以本篇主要结合官方文档研究规则持久化到 nacos
的方式。
新建 cloud-alibaba-sentinel 工程,连接 sentinel-dashboard
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>${springcloud-alibaba.version}</version>
</dependency>
server:
port: 7772
spring:
application:
name: sentinel-cloud-nacos1
cloud:
sentinel:
transport:
dashboard: localhost:8080
@RestController
public class TestController {
@GetMapping("/hello")
public Object hello(@RequestParam(required = false, defaultValue = "7") Integer i) {
return LocalDateTime.now() + " hello " + i;
}
}
- 启动sentinel-dashboard和本工程
- 密集访问 /hello 验证dashboard,图↓
- 可以看到
@RequestMapping
接口已被监控
引入 Nacos
<!--nacos的配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>${springcloud-alibaba.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
server:
port: 7772
spring:
application:
name: sentinel-cloud-nacos1
cloud:
sentinel:
transport:
dashboard: localhost:8080
nacos:
config:
# 配置中心的地址
server-addr: localhost:8848
#默认为Public命名空间,可以省略不写
#namespace: Public #命名空间,用于区分环境
#指定配置群组 --如果是Public命名空间 则可以省略群组配置
#group: DEFAULT_GROUP
#文件名 -- 如果没有配置则默认为 ${spring.appliction.name}
prefix: ${spring.application.name}
# 指定配置中心中配置文件的格式
file-extension: yml
# discovery:
# #指定注册中心的地址,如果你不需要注册该服务,也可以去掉该项,并删除discovery依赖
# server-addr: localhost:8848
# #默认为Public命名空间,可以省略不写
# namespace: Public #命名空间,用于区分环境
- 启动本地Nacos服务,添加简单的yml配置
- 编写Properties对象,映射Nacos配置,并进行访问测试验证
@ConfigurationProperties("app")
@Component
public class AppProperties {
private String author;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "AppProperties [author=" + author + "]";
}
}
@Autowired
private AppProperties appProps;
@GetMapping("/appProps")
public Object appProps() {
return appProps.toString();
}
DataSource拓展的推拉模式
- 官方文档页
- 拉(pull)模式,就是把内存中的规则持久化到文件/Naocs/Zookeeper等,应用启动加载规则,并定期轮询拉取规则。
- 推(push)模式,Dashboard可视化编辑规则到数据源(推送更新),应用监听数据源规则变动,实时更新流控规则。
- 很明显,官方推荐推模式。“我们推荐通过动态配置源的控制台来进行规则写入和推送,而不是通过 Sentinel 客户端直接写入到动态配置源中。”
改造dashboard推送配置到Nacos
<!-- for Nacos rule publisher sample -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!-- <scope>test</scope> -->
</dependency>
- 修改流控部分源码(细节参见文末链接)
- Nacos添加流控配置文件(JSON),图示↓
- 启动dashboard,并配置一个流控规则,保存查看Nacos对应文件,图示↓
客户端服务监听Nacos规则变化
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>${sentinel.version}</version>
</dependency>
@Component
public class FlowRuleNacosDataSourceConfig {
@Value("${spring.cloud.nacos.config.server-addr}")
private String sentinelNacosServerAddr;
@Value("${spring.cloud.nacos.config.namespace}")
private String sentinelNacosNamspace;
@Value("${spring.application.name}")
private String springApplicationName;
@PostConstruct
private void init() {
// remoteAddress is the address of Nacos
// groupId and dataId are concepts of Nacos
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(sentinelNacosServerAddr, sentinelNacosNamspace, "SENTINEL_GROUP", springApplicationName+"-flow-rules",
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}
- 启动服务,dashboard推送配置,客户端服务监听规则变化 ↓
2021-11-15 18:06:59.663 INFO 19996 --- [ main] c.a.n.client.config.impl.ClientWorker : [fixed-localhost_8848-st1] [subscribe] sentinel-cloud-nacos1-flow-rules+SENTINEL_GROUP+st1
2021-11-15 18:06:59.665 INFO 19996 --- [ main] c.a.nacos.client.config.impl.CacheData : [fixed-localhost_8848-st1] [add-listener] ok, tenant=st1, dataId=sentinel-cloud-nacos1-flow-rules, group=SENTINEL_GROUP, cnt=1
2021-11-15 18:06:59.671 INFO 19996 --- [alhost_8848-st1] c.a.n.client.config.impl.ClientWorker : [fixed-localhost_8848-st1] [polling-resp] config changed. dataId=sentinel-cloud-nacos1-flow-rules, group=SENTINEL_GROUP, tenant=st1
。。。。。。
2021-11-15 18:10:07.833 INFO 19996 --- [alhost_8848-st1] c.a.n.client.config.impl.ClientWorker : [fixed-localhost_8848-st1] [polling-resp] config changed. dataId=sentinel-cloud-nacos1-flow-rules, group=SENTINEL_GROUP, tenant=st1
2021-11-15 18:10:07.836 INFO 19996 --- [alhost_8848-st1] c.a.n.client.config.impl.ClientWorker : [fixed-localhost_8848-st1] [data-received] dataId=sentinel-cloud-nacos1-flow-rules, group=SENTINEL_GROUP, tenant=st1, md5=2c83f9e67d81745ea45a24dd1a7d0c63, content=[{"app":"sentinel-cloud-nacos1","clusterConfig":{"fallbackToLocalWhenFail":true,"sampleCount":10,"st...
2021-11-15 18:10:07.836 INFO 19996 --- [alhost_8848-st1] c.a.nacos.client.config.impl.CacheData : [fixed-localhost_8848-st1] [notify-listener] time cost=0ms in ClientWorker, dataId=sentinel-cloud-nacos1-flow-rules, group=SENTINEL_GROUP, md5=2c83f9e67d81745ea45a24dd1a7d0c63, listener=cn.richard.demo.sentinel.cloudnacos1.NacosDataSource$1@24312219
2021-11-15 18:10:07.837 INFO 19996 --- [update-thread-1] c.a.nacos.client.config.impl.CacheData : [fixed-localhost_8848-st1] [notify-ok] dataId=sentinel-cloud-nacos1-flow-rules, group=SENTINEL_GROUP, md5=2c83f9e67d81745ea45a24dd1a7d0c63, listener=cn.richard.demo.sentinel.cloudnacos1.NacosDataSource$1@24312219
其他注意点
- “注:一般推荐将 @SentinelResource 注解加到服务实现上,而在 Web 层直接使用 Spring Cloud Alibaba 自带的 Web 埋点适配。”
有效参考