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

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();
}
分析步骤
- nacos 配置没有自动更新,先看一下nacos 配置自动刷新的原理,然后逐步定位为什么没有自动刷新
- 先看 nacos 启动原理,找到了 NacosConfigAutoConfiguration

可以看到 nacos 自动为我们配置了很多类,其中这三个类很可能是和自动刷新配置相关的,我们一个个跟进去看具体在干什么
- 经过简单跟踪,发现第三个类为核心类 NacosContextRefresher, 进入代码
首先 ,我们先看看是否有构造前处理方法,没有发现,我们再看看构造类方法,因为刚才 NacosConfigAutoConfiguration 是直接调用的构造方法,发现构造方法中没有什么逻辑
然后,我们再分析一下这个类,发现这个类实现了 implements ApplicationListener
加断点,启动项目,发现代码就没有走到这个断点,分析

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>