Gateway 整合Sentine流控组件,并实现pull模式将API管理,网关流控规则,降级规则,系统规则持久化到文件
1、网关服务pom文件
点击查看代码
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
2、新建 PullModeLocalFileDataSource
点击查看代码
@Slf4j
public class PullModeLocalFileDataSource implements InitFunc {
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
@Override
public void init() {
log.info("time:{}读取配置", sdf.format(new Date()));
try {
// 创建文件存储目录(若路径不存在就创建路径)
RuleFileUtils.mkdirIfNotExits(PersistenceRuleConstant.storePath);
// 创建规则文件()
RuleFileUtils.createFileIfNotExits(PersistenceRuleConstant.rulesMap);
// 处理流控规则
dealFlowRules();
// 处理API规则
dealApiRules();
// 处理降级规则
dealDegradeRules();
// 处理系统规则
dealSystemRules();
} catch (Exception e) {
log.error("错误原因:{}", e);
}
}
private void dealApiRules() throws FileNotFoundException {
String ruleFilePath = PersistenceRuleConstant.rulesMap.get(PersistenceRuleConstant.API_RULE_PATH);
ReadableDataSource<String, Set<ApiDefinition>> flowRuleRDS = new FileRefreshableDataSource<>(ruleFilePath,
RuleListParserUtils.apiRuleListParser);
GatewayApiDefinitionManager.register2Property(flowRuleRDS.getProperty());
WritableDataSource<Set<ApiDefinition>> flowRuleWDS = new FileWritableDataSource<>(ruleFilePath,
RuleListParserUtils.apiRuleEnCoding);
UpdateGatewayApiDefinitionGroupCommandHandler.setWritableDataSource(flowRuleWDS);
}
/**
* 方法实现说明:处理流控规则逻辑
*/
private void dealFlowRules() throws FileNotFoundException {
String ruleFilePath = PersistenceRuleConstant.rulesMap.get(PersistenceRuleConstant.FLOW_RULE_PATH);
// 创建流控规则的可读数据源
ReadableDataSource<String, Set<GatewayFlowRule>> flowRuleRDS = new FileRefreshableDataSource<>(ruleFilePath,
RuleListParserUtils.flowRuleListParser);
// 将可读数据源注册至FlowRuleManager 这样当规则文件发生变化时,就会更新规则到内存
GatewayRuleManager.register2Property(flowRuleRDS.getProperty());
WritableDataSource<Set<GatewayFlowRule>> flowRuleWDS = new FileWritableDataSource<>(ruleFilePath,
RuleListParserUtils.flowRuleEnCoding);
// 这样收到控制台推送的规则时,Sentinel 会先更新到内存,然后将规则写入到文件中.
UpdateGatewayRuleCommandHandler.setWritableDataSource(flowRuleWDS);
}
// 处理降级规则
private void dealDegradeRules() throws FileNotFoundException {
String degradeRulePath = PersistenceRuleConstant.rulesMap.get(PersistenceRuleConstant.DEGRAGE_RULE_PATH);
// 降级规则
ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(degradeRulePath,
RuleListParserUtils.degradeRuleListParser);
DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(degradeRulePath,
RuleListParserUtils.degradeRuleEnCoding);
WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
}
// 处理系统规则
private void dealSystemRules() throws FileNotFoundException {
String systemRulePath = PersistenceRuleConstant.rulesMap.get(PersistenceRuleConstant.SYSTEM_RULE_PATH);
// 系统规则
ReadableDataSource<String, List<SystemRule>> systemRuleRDS = new FileRefreshableDataSource<>(systemRulePath,
RuleListParserUtils.systemRuleListParser);
SystemRuleManager.register2Property(systemRuleRDS.getProperty());
WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(systemRulePath,
RuleListParserUtils.systemRuleEnCoding);
WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
}
}
3、新建常量类 PersistenceRuleConstant
点击查看代码
public class PersistenceRuleConstant {
/**
* 存储文件路径
*/
public static final String storePath = System.getProperty("user.home") + "\\sentinel\\rules\\";
/**
* 各种存储sentinel规则映射map
*/
public static final Map<String, String> rulesMap = new HashMap<>();
//流控规则文件
public static final String FLOW_RULE_PATH = "gatewayFlowRulePath";
public static final String API_RULE_PATH = "apiRulePath";
//降级规则文件
public static final String DEGRAGE_RULE_PATH = "degradeRulePath";
//系统规则文件
public static final String SYSTEM_RULE_PATH = "systemRulePath";
static {
rulesMap.put(FLOW_RULE_PATH, storePath + "gatewayFlowRule.json");
rulesMap.put(DEGRAGE_RULE_PATH, storePath + "degradeRule.json");
rulesMap.put(SYSTEM_RULE_PATH, storePath + "systemRule.json");
rulesMap.put(API_RULE_PATH, storePath + "apiRule.json");
}
}
点击查看代码
@Slf4j
public class RuleFileUtils {
/**
* 方法实现说明:若路径不存在就创建路径
*
* @param filePath:文件存储路径
*/
public static void mkdirIfNotExits(String filePath) throws IOException {
File file = new File(filePath);
if (!file.exists()) {
log.info("创建Sentinel规则目录:{}", filePath);
file.mkdirs();
}
}
/**
* 方法实现说明:若文件不存在就创建路径
*
* @param ruleFileMap 规则存储文件
*/
public static void createFileIfNotExits(Map<String, String> ruleFileMap) throws IOException {
Set<String> ruleFilePathSet = ruleFileMap.keySet();
Iterator<String> ruleFilePathIter = ruleFilePathSet.iterator();
while (ruleFilePathIter.hasNext()) {
String ruleFilePathKey = ruleFilePathIter.next();
String ruleFilePath = PersistenceRuleConstant.rulesMap.get(ruleFilePathKey);
File ruleFile = new File(ruleFilePath);
if (ruleFile.exists()) {
log.info("创建Sentinel 规则文件:{}", ruleFile);
ruleFile.createNewFile();
}
}
}
}
点击查看代码
public class RuleListParserUtils {
/**
* 流控列表解析器
*/
public static final Converter<String, Set<GatewayFlowRule>> flowRuleListParser =
source -> JSON.parseObject(source, new TypeReference<Set<GatewayFlowRule>>() {
});
/**
* 流控列表 编码器
*/
public static final Converter<Set<GatewayFlowRule>, String> flowRuleEnCoding = JSON::toJSONString;
public static final Converter<Set<ApiDefinition>, String> apiRuleEnCoding = JSON::toJSONString;
public static final Converter<String, Set<ApiDefinition>> apiRuleListParser = source -> {
Set<ApiDefinition> apiDefinitionSet = new HashSet<>();
Set<JSONObject> set = JSON.parseObject(source, Set.class);
for (JSONObject o : set) {
ApiDefinition apiDefinition = new ApiDefinition();
apiDefinition.setApiName(o.getString("apiName"));
JSONArray predicateItems = o.getJSONArray("predicateItems");
Set<ApiPredicateItem> apiPredicateItems = new HashSet<>();
for (Object item : predicateItems) {
JSONObject object = (JSONObject) item;
ApiPathPredicateItem apiPathPredicateItem = new ApiPathPredicateItem();
apiPathPredicateItem.setMatchStrategy(object.getIntValue("matchStrategy"));
apiPathPredicateItem.setPattern(object.getString("pattern"));
apiPredicateItems.add(apiPathPredicateItem);
}
apiDefinition.setPredicateItems(apiPredicateItems);
apiDefinitionSet.add(apiDefinition);
}
return apiDefinitionSet;
};
public static final Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(source,
new TypeReference<List<DegradeRule>>() {
});
public static final Converter<List<DegradeRule>, String> degradeRuleEnCoding = JSON::toJSONString;
public static final Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(source,
new TypeReference<List<SystemRule>>() {
});
public static final Converter<List<SystemRule>, String> systemRuleEnCoding = JSON::toJSONString;
}
com.test.init.DataSourceInitFunc
7、启动sentilel控制台,新建的规则会自动持久化到文件中
8、https://blog.csdn.net/huangjinjin520/article/details/107572592
9、修改流控规则报空指针异常问题:升级spring-cloud-alibaba版本,sentinel 1.8.0 整合网关有bug
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通