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
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号