集群多节点动态刷新方案-Nacos配置修改监听

本篇就不对Nacos做基本介绍使用了。
紧接上篇,解决集群下动态刷新规则的问题。

前言

  • 上篇提到两个方案
    • 使用MQ对节点进行广播
    • 使用Nacos
  • 由于工作中深度使用到了Nacos,所以本次利用Nacos特性实现。
  • Nacos很强大,直接包揽服务注册、配置中心,且更有国人特色。
  • Nacos支持配置修改毫秒级实时生效,官方还提供了配置更新监听且自带多节点广播特点,本次重点利用这个特性。
  • 另外,Nacos提供了API可主动修改目标配置文件,产生change事件,这也是本次要利用的特性。

快速开始

工程引入Nacos

直接在上篇springboot工程基础上进行改造。

  • pom新增Nacos依赖
    <dependency>
    	<groupId>com.alibaba.cloud</groupId>
    	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
    	<groupId>com.alibaba.cloud</groupId>
    	<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    
  • application.yml 重命名为 bootstrap.yml,并添加Nacos相关配置
    spring:
      application:
        name: @project.artifactId@ 
      profiles:
        active: local
        
      thymeleaf:
        cache: false
      
      cloud:
        nacos:
          config: 
            server-addr: 127.0.0.1:8848
            # 默认为public命名空间,可以省略不写
            #namespace: local #命名空间,用于区分环境或者个人使用
            # 指定配置群组 --如果是Public命名空间 则可以省略群组配置
            #group: DEFAULT_GROUP
            # 文件名 -- 如果没有配置则默认为 ${spring.appliction.name}
            #prefix: ${spring.application.name}
            # 指定配置中心中配置文件的格式
            file-extension: yml
          discovery:
            # 指定注册中心的地址,如果你不需要注册该服务,也可以去掉该项,并删除discovery依赖
            server-addr: 127.0.0.1:8848
            # 默认为public命名空间,可以省略不写
            #namespace: local #命名空间,用于区分环境
            
    app:
      drools:
        # 配置Drools决策表文件路径,可多个
        xlsFilePaths:
        - D:/temp/person_check.xls
    
  • 启动本地的Nacos服务
  • 启动工程,注意日志
  • 查看Nacos控制台服务注册列表:http://127.0.0.1:8848/nacos/
  • 验证上篇功能

Nacos配置修改监听与集群广播

  • 在Nacos控制台添加一个extend配置文件(drools-reload-flag-local.yml,命名空间和分组都采用默认),内容则无所谓
    新增Nacos配置文件
  • bootstrap.yml 的nacos配置中心部分添加拓展配置文件读取
    server-addr: 127.0.0.1:8848
    # 默认为public命名空间,可以省略不写
    #namespace: local #命名空间,用于区分环境或者个人使用
    # 指定配置群组 --如果是Public命名空间 则可以省略群组配置
    #group: DEFAULT_GROUP
    # 文件名 -- 如果没有配置则默认为 ${spring.appliction.name}
    #prefix: ${spring.application.name}
    # 指定配置中心中配置文件的格式
    file-extension: yml
    # 额外文件引入
    extension-configs:
    - data-id: drools-reload-flag-${spring.profiles.active}.yml
      group: DEFAULT_GROUP
      refresh: true
    
  • 重启查看日志读取情况,可以看到配置已经被发现且被默认监听
    : Started BootDroolsNacos in 6.095 seconds (JVM running for 7.185)
    : [fixed-127.0.0.1_8848] [add-listener] ok, tenant=, dataId=drools-springboot-nacos.yml, group=DEFAULT_GROUP, cnt=1
    : [fixed-127.0.0.1_8848] [add-listener] ok, tenant=, dataId=drools-springboot-nacos, group=DEFAULT_GROUP, cnt=1
    : [fixed-127.0.0.1_8848] [add-listener] ok, tenant=, dataId=drools-springboot-nacos-local.yml, group=DEFAULT_GROUP, cnt=1
    : [fixed-127.0.0.1_8848] [add-listener] ok, tenant=, dataId=drools-reload-flag-local.yml, group=DEFAULT_GROUP, cnt=1
    
  • 定义配置Bean获取该配置内容,虽然不会用到...
    @Component
    @ConfigurationProperties(prefix = "drools-reload-flag")
    @Data
    public class DroolsReloadFlagConfigPropertiesBean {
    	private Long timestamp;
    	private String updator;
    }
    
  • controller测试
    @Autowired
    private DroolsReloadFlagConfigPropertiesBean droolsReloadFlagConfigPropertiesBean;
    @GetMapping("/rule/propeties")
    public Object ruleProperties() {
    	//实时修改生效(添加了文件需要重启Nacos?)
    	return droolsReloadFlagConfigPropertiesBean;
    }
    
  • 添加Nacos目标配置文件修改监听
    try {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
        ConfigService configService = NacosFactory.createConfigService(properties);
        
        String content = configService.getConfig(dataId, group, 5000);
        if (StringUtils.isEmpty(content)) {
            log.warn("目标配置内容为空,跳过监听");
            return;
        }
        log.info("初始配置内容读取: {}", content);
        log.info("开始注册修改监听: {}", dataId);
        configService.addListener(dataId, group, new Listener() {
    
            @Override
            public void receiveConfigInfo(String configInfo) {
                log.info("{} 本次修改后的内容: {}", dataId, configInfo);
                //业务逻辑部分,即刷新规则
                kieUtilService.reload();
            }
    
            @Override
            public Executor getExecutor() {
                return null;
            }
        });
        log.info("结束注册修改监听: {}", dataId);
    } catch (NacosException e) {
        log.error("Nacos配置相关异常:{}", e.getMessage());
        throw new RuntimeException("Nacos配置读取与修改监听", e);
    }
    
  • OK

Nacos主动public触发文件更新监听

  • 和监听一样,需要用到Nacos的ConfigService
  • Nacos的控制台其实已经有实例,可对目标配置文件进行内容读取、文件删除、内容更新/覆盖,如图↓
    nacos实例代码截图
  • 可以对其进行简单封装,然后写一个controller方法测试下内容修改,测试是否监听到
    @Autowired
    private DroolsReloadFlagConfigListener droolsReloadFlagConfigListener;
    @GetMapping("/rule/config/publish")
    public Object ruleConfigPublish() throws NacosException {
    	droolsReloadFlagConfigListener.publishConfig(LocalDateTime.now().toString());
    	
    	return "OK";
    }
    
  • 单节点测试监听OK后,就可以测试下Nacos服务注册多节点的监听广播了。STS下快速复制注册一个节点很容易,在BootDashboard下对当前的应用Duplicate下,然后修改VM参数端口启动即可,如图↓
    STS快速多节点测试截图
  • 收工

小结

  • 本文是紧接Drools的,但标题并没有继续取名和Drools相关,因为这种方式是一种Nacos服务注册列表的广播方案,和具体业务无关,可以用于各个场景。
  • 本次demo源码就是上篇工程,只不过对其进行了改造。
  • 下篇预告:将springboot依赖工程starter化
  • 原文地址,欢迎交流
  • love & peace
posted @ 2020-09-12 17:27  summaster  阅读(4974)  评论(0编辑  收藏  举报