Sentinel+Nacos限流规则持久化项目实战
本文介绍了如何通过Sentinel+Nacos限流规则持久化项目实战,实现了动态管理和更新限流规则。首先搭建了开发环境并配置了必要的依赖,接着详细讲解了如何编写和持久化限流规则,最后通过模拟高并发场景验证了系统的限流能力。
引入Sentinel和NacosSentinel简介
Sentinel 是一款开源的、分布式的流量控制组件,旨在提供高可用和弹性的保护能力。它不仅可以限制单个应用接口的流量,还可以对整个应用和集群进行流量控制。Sentinel 通过将规则应用到资源来实现这一功能,资源可以是任何有业务含义的逻辑单元,例如一个方法或一个url。
Nacos简介
Nacos 是一个动态服务发现、配置管理和服务管理平台,它可以帮助您实现微服务架构下的动态服务发现、服务管理以及服务配置管理功能。Nacos 提供了一个开放的API,允许用户通过编程的方式对服务进行动态配置和管理。
为什么选择Sentinel+Nacos组合
Sentinel 提供了强大的流量控制功能,但其规则需要手动配置或通过代码动态设置。Nacos 的配置管理功能正好可以弥补这一不足,它允许用户将限流规则持久化到配置服务器上,使得规则的更新和管理更加简便。通过将Sentinel集成到Nacos中,可以实现限流规则的动态更新和持久化存储,提高系统的灵活性和可管理性。
环境搭建及依赖配置开发环境搭建
首先,确保您的机器上已经安装了Java开发工具包(JDK)和Maven或Gradle构建工具。然后,您可以创建一个新的Java项目,选择合适的Maven或Gradle项目模板来启动。
初始化Maven或Gradle依赖
以Maven为例,您需要在项目的 pom.xml
文件中添加Sentinel和Nacos的依赖。对于Sentinel,添加如下依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel</artifactId>
<version>1.8.2</version>
</dependency>
对于Nacos,添加如下依赖:
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.0.3</version>
</dependency>
配置Sentinel和Nacos
在 application.properties
文件中,添加Nacos的配置信息,例如服务地址、端口等。同时,配置Sentinel客户端以连接Nacos服务器。
nacos.server-addr=127.0.0.1:8848
sentinel.server-lists=nacos://127.0.0.1:8848
基本限流规则编写
创建和配置资源
在Sentinel中,资源是指需要进行流量控制的逻辑单元。资源可以是一个方法、一个url或任何其他业务逻辑。首先,定义一个资源:
public class ResourceTest {
public static void main(String[] args) {
// 创建资源
String resourceName = "exampleResource";
Entry entry = SphU.entry(resourceName);
// 需要执行的业务逻辑
System.out.println("资源通过流量控制!");
// 释放资源
entry.exit();
}
}
编写基本限流规则
使用Sentinel API为资源设置限流规则。例如,限制每秒最多10次访问:
private static void setFlowRule(String resourceName) {
FlowRule rule = new FlowRule(resourceName);
rule.setCount(10);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitCount(10);
FlowRuleManager.loadRules(Collections.singletonList(rule));
}
测试规则有效性
在主函数中调用设置规则的函数,并进行一些测试调用来验证规则的有效性。
public static void main(String[] args) {
setFlowRule("exampleResource");
// 测试规则
for (int i = 0; i < 15; i++) {
Entry entry = SphU.entry("exampleResource");
System.out.println("请求: " + i);
entry.exit();
}
}
运行程序可以看到,前10次请求通过,但第11次和之后的请求会被限流。
限流规则持久化连接Nacos服务器
首先,需要初始化Nacos客户端并连接到Nacos服务器。
import com.alibaba.nacos.api.NacosClient;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
public class NacosClientExample {
public static void main(String[] args) throws NacosException {
String serverAddr = "127.0.0.1:8848";
String dataId = "sentinel-rules";
String group = "DEFAULT_GROUP";
// 初始化Nacos客户端
NacosClient nacosClient = NacosClient.createClient(serverAddr);
// 获取配置服务
ConfigService configService = nacosClient.getConfigService();
// 订阅配置变化
configService.getConfig(dataId, group, new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("Received config info: " + configInfo);
}
});
}
}
将限流规则保存至Nacos
将当前的限流规则序列化为JSON格式,然后将其保存到Nacos配置服务器中。
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import java.util.Properties;
public class RulePersistenceExample {
@NacosValue(value = "${sentinel.rules:[]}", autoRefresh = true)
private String sentinelRulesJson;
public void saveRulesToNacos(ConfigService configService) throws NacosException {
List<FlowRule> rules = FlowRuleManager.getRules();
String rulesJson = JSON.toJSONString(rules);
configService.publishConfig("sentinel-rules", "DEFAULT_GROUP", rulesJson);
}
}
从Nacos读取限流规则
从Nacos中读取当前的规则,并将其加载到Sentinel中。
public void loadRulesFromNacos(ConfigService configService) throws NacosException {
String rulesJson = configService.getConfig("sentinel-rules", "DEFAULT_GROUP");
List<FlowRule> rules = JSON.parseArray(rulesJson, FlowRule.class);
FlowRuleManager.loadRules(rules);
}
实战演练:模拟高并发场景
创建模拟高并发场景
使用多线程模拟高并发场景。每个线程代表一个请求,可以设置线程的数量来模拟不同级别的并发。
public class HighConcurrencyTest {
public static void main(String[] args) {
int threadCount = 20;
ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
for (int i = 0; i < threadCount; i++) {
executorService.execute(() -> {
Entry entry = SphU.entry("exampleResource");
System.out.println("请求通过限流: " + Thread.currentThread().getName());
entry.exit();
});
}
executorService.shutdown();
}
}
应用持久化的限流规则
在上述模拟高并发场景的代码中,确保限流规则已经从Nacos加载到Sentinel中。
public class Main {
public static void main(String[] args) throws NacosException {
// 初始化Nacos客户端并从Nacos加载规则
ConfigService configService = new NacosClient().getConfigService();
RulePersistenceExample example = new RulePersistenceExample();
example.loadRulesFromNacos(configService);
// 启动高并发测试
new HighConcurrencyTest().main(new String[]{});
}
}
在高并发场景下验证限流规则
运行高并发测试代码,观察输出结果。由于限流规则已经设置为每秒最多10次请求,故实际请求量将被限制。验证不同并发级别的表现,确保限流规则正确实施。
小结与常见问题解决总结项目实战经验
在整个项目实战过程中,我们学习了如何利用Sentinel进行基本的限流规则设置,并使用Nacos来实现规则的持久化。通过这种方式,可以动态调整限流策略而无需重启应用,从而提高了系统的灵活性。
常见问题及解决方案
- Nacos连接失败:检查Nacos服务器地址、端口等配置信息是否正确,确保Nacos服务器处于运行状态。
- 规则同步延迟:Nacos默认的配置同步间隔可能较长,可以通过配置监听器实现更及时的规则同步。
- 资源名称未找到:确保资源名称在Sentinel的资源列表中存在,并且名称拼写正确。
Q&A环节
Q: 如何查看Sentinel已加载的规则列表?
A: 可以调用 FlowRuleManager.getRules()
方法来获取当前加载的所有限流规则。该方法返回一个 List<FlowRule>
对象,其中每个对象包含了具体的规则信息。
List<FlowRule> rules = FlowRuleManager.getRules();
System.out.println(rules);
Q: Nacos配置数据丢失怎么办?
A: 如果Nacos配置数据丢失,可以通过之前保存的规则文件或手动重新配置规则来恢复。确保在开发环境中保存重要的配置信息以备不时之需。
RulePersistenceExample example = new RulePersistenceExample();
example.saveRulesToNacos(configService);
共同学习,写下你的评论
评论加载中...
作者其他优质文章