本文主要是介绍【自研网关系列】整合 Nacos 配置拉取与配置变更信息的订阅,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
🌈Yu-Gateway::基于 Netty 构建的自研 API 网关,采用 Java 原生实现,整合 Nacos 作为注册配置中心。其设计目标是为微服务架构提供高性能、可扩展的统一入口和基础设施,承载请求路由、安全控制、流量治理等核心网关职能。
🌈项目代码地址:GitHub - YYYUUU42/YuGateway-master
如果该项目对你有帮助,可以在 github 上点个 ⭐ 喔 🥰🥰
🌈自研网关系列:可以点开专栏,参看完整的文档
目录
1、将配置弄到 Nacos 上
2、编写配置中心接口
3、实现流程
1、将配置弄到 Nacos 上
配置在项目底下有
配置文件含义可以在核心请求url的规则匹配类中查看,有详细注解
2、编写配置中心接口
上偏文章主要就是实现注册中心的服务注册功能,这里就实现配置中心的配置拉取以及配置变更监听的功能。
首先还是需要定义一个配置中心接口来初始化配置中心配置以及配置中心信息变更事件
/*** @author yu* @description 配置中心接口方法*/
public interface ConfigCenter {/*** 初始化配置中心配置** @param serverAddr 配置中心地址* @param env 环境*/void init(String serverAddr, String env);/*** 订阅配置中心配置变更** @param listener 配置变更监听器*/void subscribeRulesChange(RulesChangeListener listener);
}
/*** @author yu* @description 规则变更监听器*/
public interface RulesChangeListener {/*** 规则变更时调用此方法 对规则进行更新** @param rules 新规则*/void onRulesChange(List<Rule> rules);
}
3、实现流程
这里依然会用 debug 的方式进行详细讲
完整启动代码:
public static void main(String[] args) {//加载网关核心静态配置Config config = ConfigLoader.getInstance().load(args);//插件初始化//配置中心管理器初始化,连接配置中心,监听配置的新增、修改、删除ServiceLoader<ConfigCenter> serviceLoader = ServiceLoader.load(ConfigCenter.class);final ConfigCenter configCenter = serviceLoader.findFirst().orElseThrow(() -> {log.error("can't found ConfigCenter impl");return new RuntimeException("can't found ConfigCenter impl");});//从配置中心获取数据configCenter.init(config.getRegistryAddress(), config.getEnv());configCenter.subscribeRulesChange(new RulesChangeListener() {@Overridepublic void onRulesChange(List<Rule> rules) {DynamicConfigManager.getInstance().putAllRule(rules);}});//启动容器Container container = new Container(config);container.start();//连接注册中心final RegisterCenter registerCenter = registerAndSubscribe(config);//服务停机//收到 kill 信号时触发,服务停机Runtime.getRuntime().addShutdownHook(new Thread() {/*** 服务停机*/@Overridepublic void run() {registerCenter.deregister(buildGatewayServiceDefinition(config),buildGatewayServiceInstance(config));container.shutdown();}});}
首先,还是一样从 META-INF/services 下利用 SPI 获取实现类
ServiceLoader<ConfigCenter> serviceLoader = ServiceLoader.load(ConfigCenter.class);
final ConfigCenter configCenter = serviceLoader.findFirst().orElseThrow(() -> {log.error("can't found ConfigCenter impl");return new RuntimeException("can't found ConfigCenter impl");
});
初始化:将配置中的信息弄到配置中心那里,主要还是创建一个 ConfigService,是 Nacos 提供的与配置中心进行交互的接口
/**
* 初始化配置中心配置
*
* @param serverAddr 配置中心地址
* @param env 环境
*/
@Override
public void init(String serverAddr, String env) {this.serverAddr = serverAddr;this.env = env;try {this.configService = NacosFactory.createConfigService(serverAddr);} catch (NacosException e) {log.error("NacosConfigCenter init failed ", e);throw new RuntimeException(e);}
}
初始化完成后,就要开始订阅配置中心配置变更,
完整代码:
/**
* 订阅配置中心配置变更
*
* @param listener 配置变更监听器
*/
@Override
public void subscribeRulesChange(RulesChangeListener listener) {
try {//初始化通知 DATA_ID是自己定义的 返回值就是一个json configJson : {"rules":[{}, {}]}String msg = configService.getConfig(DATA_ID, env, 5000);log.info("Rules-Config From Nacos: {}", msg);List<Rule> rules = JSON.parseObject(msg).getJSONArray("rules").toJavaList(Rule.class);// 保存配置信息到本地,调用我们的监听器 参数就是我们拿到的ruleslistener.onRulesChange(rules);// 配置远程注册中心配置变更的回调函数configService.addListener(DATA_ID, env, new Listener() {//是否使用额外线程执行@Overridepublic Executor getExecutor() {return null;}//调用监听器的 onRulesChange 方法,将解析得到的 Rule 对象列表作为参数传递给监听器,以通知配置变更。@Overridepublic void receiveConfigInfo(String configInfo) {log.info("new Config from Nacos: {}", configInfo);List<Rule> newRules = JSON.parseObject(configInfo).getJSONArray("rules").toJavaList(Rule.class);listener.onRulesChange(newRules);}});
} catch (NacosException e) {log.error("subscribeRulesChange failed", e);throw new RuntimeException(e);
}
}
第一步就是从 nacos 上拿到配置文件
将规则信息保存配置信息到本地,这个方法的实现在我们启动类处。创建了一个新的 RulesChangeListener 匿名内部类,并重写了 onRulesChange 方法。当配置中心的规则发生变化时,onRulesChange 方法会被调用,然后将新的规则放入 DynamicConfigManager 的规则映射中。
总的来说,这段代码的作用是根据传入的 Rule 对象列表,更新 DynamicConfigManager 类中的三个映射,以便在后续的操作中快速查找和访问 Rule 对象
public void putAllRule(List<Rule> ruleList) {ConcurrentHashMap<String, Rule> newRuleMap = new ConcurrentHashMap<>();ConcurrentHashMap<String, Rule> newPathMap = new ConcurrentHashMap<>();ConcurrentHashMap<String, List<Rule>> newServiceMap = new ConcurrentHashMap<>();for (Rule rule : ruleList) {newRuleMap.put(rule.getId(), rule);List<Rule> rules = newServiceMap.get(rule.getServiceId());if (rules == null) {rules = new ArrayList<>();}rules.add(rule);newServiceMap.put(rule.getServiceId(), rules);List<String> paths = rule.getPaths();for (String path : paths) {String key = rule.getServiceId() + "." + path;newPathMap.put(key, rule);}}ruleMap = newRuleMap;pathRuleMap = newPathMap;serviceRuleMap = newServiceMap;
}
最后就是向 Nacos 的监听器列表添加一个我们的监听器,当 Nacos 的配置发送变更时,就可以监听到这个事件,然后执行我们所希望的逻辑
这篇关于【自研网关系列】整合 Nacos 配置拉取与配置变更信息的订阅的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!