如下分析基于nacos-client-2.2.4。 Nacos的定时刷新是在客户端实现的,具体来说是在com.alibaba.nacos.client.config.impl.ClientWorker
类中。 在ClientWorker
的构造函数中实例化了一个ScheduledExecutorService
定时任务线程池,该定时任务线程池用于执行定时登录操作和启动定时刷新配置信息操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public ClientWorker (final ConfigFilterChainManager configFilterChainManager, ServerListManager serverListManager, final NacosClientProperties properties) throws NacosException { this .configFilterChainManager = configFilterChainManager; init(properties); agent = new ConfigRpcTransportClient (properties, serverListManager); int count = ThreadUtils.getSuitableThreadCount(THREAD_MULTIPLE); ScheduledExecutorService executorService = Executors.newScheduledThreadPool(Math.max(count, MIN_THREAD_NUM), r -> { Thread t = new Thread (r); t.setName("com.alibaba.nacos.client.Worker" ); t.setDaemon(true ); return t; }); agent.setExecutor(executorService); agent.start(); }
并将该定时任务线程池作为com.alibaba.nacos.client.config.impl.ConfigTransportClient
的executor
属性。 在com.alibaba.nacos.client.config.impl.ConfigTransportClient
的start()
方法中,启动了定时登录任务和定时获取配置信息的操作。
1 2 3 4 5 6 7 public void start () throws NacosException { securityProxy.login(this .properties); this .executor.scheduleWithFixedDelay(() -> securityProxy.login(properties), 0 , this .securityInfoRefreshIntervalMills, TimeUnit.MILLISECONDS); startInternal(); }
在com.alibaba.nacos.client.config.impl.ClientWorker.$ConfigRpcTransportClient
的startInternal()
方法中,通过一个while
循环启动了一个定时刷新配置的操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public void startInternal () { executor.schedule(() -> { while (!executor.isShutdown() && !executor.isTerminated()) { try { listenExecutebell.poll(5L , TimeUnit.SECONDS); if (executor.isShutdown() || executor.isTerminated()) { continue ; } executeConfigListen(); } catch (Throwable e) { LOGGER.error("[rpc listen execute] [rpc listen] exception" , e); try { Thread.sleep(50L ); } catch (InterruptedException interruptedException) { } notifyListenConfig(); } } }, 0L , TimeUnit.MILLISECONDS); }
每隔5秒钟就会执行com.alibaba.nacos.client.config.impl.ClientWorker.$ConfigRpcTransportClient
的executeConfigListen()
方法检查并获取最新配置的操作,更加具体地说,是在com.alibaba.nacos.client.config.impl.ClientWorker.$ConfigRpcTransportClient
的checkListenCache()
方法中检查并刷新配置信息的,完整的执行活动图如下所示。
当我们在属性中使用了注解@NacosValue
并将autoRefreshed
属性设置为true,在应用启动时会将这些使用了@NacosValue
注解的属性信息保存在NacosValueAnnotationBeanPostProcessor
的placeholderNacosValueTargetMap
属性集合中,当在com.alibaba.nacos.client.config.impl.ClientWorker
中通过定时任务检测到属性的配置内容有更新时就会使用Spring事件机制发布通知,并在NacosValueAnnotationBeanPostProcessor
的onApplicationEvent
方法中完成对属性内容的更新。
1 2 3 @NacosValue(value = "${user.id}", autoRefreshed = true) private String userId;
1 2 3 4 5 6 7 8 9 10 11 @Override public void onApplicationEvent (NacosConfigReceivedEvent event) { for (Map.Entry<String, List<NacosValueTarget>> entry : placeholderNacosValueTargetMap .entrySet()) { } }