开发者社区 > 云原生 > 正文

Spring Cloud gateway 整合Sentines 做限流时持久化到Redis不生效

我在使用Spring Cloud 整合Sentines做限流时,想把规则数据存到Redis中,Sentines官方文档是支持持久化到Redis的,但是我按照官方文档继承AbstractDataSource接口后,不知道该如何调用这个类。

在启动Spring Cloud项目时,应该如何传入Redis Config 参数和redis 的ruleKey,以及如何让我重写的这个类起作用呢?

不用重写AbstractDataSource类,只需要创建一个项目启动类,并使用默认的实现类即可: `package cn.com.bobfintechgateway.sentinel;

import java.util.List;

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component;

import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.datasource.ReadableDataSource; import com.alibaba.csp.sentinel.datasource.redis.RedisDataSource; import com.alibaba.csp.sentinel.datasource.redis.config.RedisConnectionConfig; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference;

/**

@project: 北银金科 @description: 客户端在启动时初始化Redis中规则 @Version 1.0.0 @errorcode

   错误码: 错误描述

@author

<li>2020-07-17 guopengfei@bobfintech.com.cn Create 1.0

@copyright ©2019-2020 北银金科,版权所有。

*/ @component public class RedisDataSourceConfig implements ApplicationRunner { private static final Logger log = LoggerFactory.getLogger(RedisDataSourceConfig.class);

@value("${spring.redis.host}") public String redisHost;

@value("${spring.redis.port}") public int redisPort;

@value("${spring.redis.password}") public String redisPass;

@value("${spring.redis.database}") public Integer database;

//限流规则key前缀 public final String RULE_FLOW = "sentinel_rule_flow_"; public final String RULE_FLOW_CHANNEL = "sentinel_rule_flow_channel";

//降级规则key前缀 // public final String RULE_DEGRADE = "sentinel_rule_degrade_"; // public final String RULE_DEGRADE_CHANNEL = "sentinel_rule_degrade_channel";

//系统规则key前缀 // public final String RULE_SYSTEM = "sentinel_rule_system_"; // public final String RULE_SYSTEM_CHANNEL = "sentinel_rule_system_channel";

/**

ApplicationRunner

该接口的方法会在服务启动之后被立即执行

主要用来做一些初始化的工作

但是该方法的运行是在SpringApplication.run(…​) 执行完毕之前执行 */ @OverRide public void run(ApplicationArguments args) { log.info("执行sentinel规则初始化 start >>>>>>>>>>>>>"); RedisConnectionConfig config = RedisConnectionConfig.builder().withHost(redisHost).withPort(redisPort) .withPassword(redisPass).withDatabase(database).build(); Converter<String, List> parser = source -> JSON.parseObject(source, new TypeReference() {});

ReadableDataSource<String, List> redisDataSource = new RedisDataSource<>(config, RULE_FLOW, RULE_FLOW_CHANNEL, parser); FlowRuleManager.register2Property(redisDataSource.getProperty()); log.info("执行sentinel规则初始化 end >>>>>>>>>>>>>");

// Converter<String, List> parserDegrade = source -> JSON.parseObject(source, // new TypeReference() { // }); // ReadableDataSource<String, List> redisDataSourceDegrade = new // RedisDataSource<>(config, RULE_DEGRADE + SentinelConfig.getAppName(), // RULE_DEGRADE_CHANNEL, parserDegrade); // DegradeRuleManager.register2Property(redisDataSourceDegrade.getProperty());

// Converter<String, List> parserSystem = source -> JSON.parseObject(source, new // TypeReference() { // }); // ReadableDataSource<String, List> redisDataSourceSystem = new // RedisDataSource<>(config, RULE_SYSTEM + SentinelConfig.getAppName(), RULE_SYSTEM_CHANNEL, // parserSystem); // SystemRuleManager.register2Property(redisDataSourceSystem.getProperty()); log.info(">>>>>>>>>执行sentinel规则初始化 end。。。"); }

}` 原提问者GitHub用户wangmingweikong

展开
收起
学习娃 2023-05-19 16:07:13 97 0
1 条回答
写回答
取消 提交回答
  • 我改为拉取模式后也没有效过;我的做法是在sentinel-dashboard 加两个接口,然后client 启动时候去调这两个接口,让服务端主动推送过来(当然我还加了延迟,让client与server通信后才发起请求)。

    原回答者GitHub用户keybersan

    2023-05-19 20:49:35
    赞同 展开评论 打赏

阿里云拥有国内全面的云原生产品技术以及大规模的云原生应用实践,通过全面容器化、核心技术互联网化、应用 Serverless 化三大范式,助力制造业企业高效上云,实现系统稳定、应用敏捷智能。拥抱云原生,让创新无处不在。

相关电子书

更多
Redis集群演化的心路历程——从2.x到3.0时代 立即下载
微博的Redis定制之路 立即下载
云数据库Redis版的开源之路 立即下载