Nacos 配置没有自动更新

Nacos 配置没有自动更新

Posted by lijian on October 10, 2020

现状

  1. 系统启动配置了动态刷新(即使不配置默认也是动态刷新的)
  2. springboot 项目,启动类直接实现 CommandLineRunner , 期望在springboot 启动后启动 netty-server

微信截图_20210112114218.png

import com.google.common.reflect.TypeToken;
import com.jovision.jcmp.mps.remoting.ChannelEventProcessor;
import com.jovision.jcmp.mps.remoting.MsgProcessor;
import com.jovision.jcmp.netty.NettyServer;
import com.jovision.jcmp.service.ServerStartedListener;
import com.jovision.jcmp.service.impl.MpsServerConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

import javax.annotation.Resource;
import java.util.List;

@Slf4j
@ServletComponentScan
@EnableFeignClients
@SpringCloudApplication
public class MpsNettyApplication implements CommandLineRunner {

    @Autowired
    @Qualifier("serverChannelEventListener")
    private ChannelEventProcessor channelEventProcessor;
    @Autowired
    @Qualifier("serverMsgProcessor")
    private MsgProcessor msgProcessor;
    @Autowired
    private MpsServerConfigService mpsServerConfigService;
    @Resource
    private ServerStartedListener serverStartedListener;

    public static void main(String[] args) {
        String nettyHost = System.getProperty("nettyHost");
        String nettyPort = System.getProperty("nettyPort");
        if (StringUtils.isEmpty(nettyHost) || StringUtils.isEmpty(nettyPort)) {
            throw new RuntimeException("system property nettyHost or nettyPort failed");
        }
        System.out.println(nettyHost);
        System.out.println(Integer.parseInt(nettyPort));
        SpringApplication.run(MpsNettyApplication.class, args);
        log.info("MpsNettyApplication started ...");
    }

    @Override
    public void run(String... args) throws Exception {
        new NettyServer(mpsServerConfigService.getCerPath(), mpsServerConfigService.getStorePassword(), mpsServerConfigService.getKeyPassword(), mpsServerConfigService.getTcpIdleSeconds(),
                msgProcessor, channelEventProcessor, serverStartedListener)
                .start();
    }

分析步骤

  1. nacos 配置没有自动更新,先看一下nacos 配置自动刷新的原理,然后逐步定位为什么没有自动刷新
  2. 先看 nacos 启动原理,找到了 NacosConfigAutoConfiguration 微信截图_20210112114847.png

可以看到 nacos 自动为我们配置了很多类,其中这三个类很可能是和自动刷新配置相关的,我们一个个跟进去看具体在干什么

  1. 经过简单跟踪,发现第三个类为核心类 NacosContextRefresher, 进入代码 微信截图_20210112115131.png 首先 ,我们先看看是否有构造前处理方法,没有发现,我们再看看构造类方法,因为刚才 NacosConfigAutoConfiguration 是直接调用的构造方法,发现构造方法中没有什么逻辑

然后,我们再分析一下这个类,发现这个类实现了 implements ApplicationListener, ApplicationContextAware 两个接口,查看对应的接口逻辑 ![微信截图_20210112115502.png](https://i.loli.net/2021/01/12/8l9mr7b4HF6SguI.png) 很明显 ApplicationContextAware 实现方法没有逻辑,代码逻辑都在 registerNacosListenersForApplications 方法中

加断点,启动项目,发现代码就没有走到这个断点,分析

微信截图_20210112115951.png

netty server 是一个commandline 启动后会抓住线程,不继续往下走,没有执行 listener.running 方法

修改netty server 不使用 commanline 方式,单独自己启动,修改之后配置实时更新

PS

注意 无论是 nacos 还是 Apollo 与 jasypt 兼容都有问题,会造成配置不实时更新

 <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>${jasypt.version}</version>
        </dependency>