上篇文章《Nacos 配置中心原理分析》我和大家分析了 Nacos 的配置中心原理,主要分析了 Nacos 客户端是如何感知到服务端的配置变更的,但是只是从客户端的角度进行了分析,并没有从服务端的角度进行分析,本篇文章我将结合服务端从两个角度来分析配置变更是如何通知到客户端的。
PS:文章有点长,因为涉及到多个细节需要阐述,如果看不下去的话,可以直接转到文末看结论即可。
一、客户端
从上篇文章中我们已经知道了 Nacos 的客户端维护了一个长轮询的任务,去检查服务端的配置信息是否发生变更,如果发生了变更,那么客户端会拿到变更的 groupKey 再根据 groupKey 去获取配置项的最新值即可。
每次都靠客户端去发请求,询问服务端我所关注的配置项有没有发生变更,那请求的间隔改设置为多少才合适呢?
如果间隔时间设置的太长的话有可能无法及时获取服务端的变更,如果间隔时间设置的太短的话,那么频繁的请求对于服务端来说无疑也是一种负担。
所以最好的方式是客户端每隔一段长度适中的时间去服务端请求,而在这期间如果配置发生变更,服务端能够主动将变更后的结果推送给客户端,这样既能保证客户端能够实时感知到配置的变化,也降低了服务端的压力。
客户端长轮询
现在让我们再次回到客户端长轮询的部分,也就是 LongPollingRunnable 中的 checkUpdateDataIds 方法,该方法就是用来访问服务端的配置是否发生变更的,该方法最终会调用如下图所示的方法:
check-update-config.jpg
请注意图中红框部分的内容,客户端是通过一个 http 的 post 请求去获取服务端的结果的,并且设置了一个超时时间:30s。
这个信息很关键,为什么客户端要等待 30s 才超时呢?不应该越快得到结果越好吗,我们来验证下该方法是不是真的等待了 30s。
在 LongPollingRunnable 中的 checkUpdateDataIds 方法前后加上时间计算,然后将所消耗的时间打印出来,如下图所示:
print-cost-check-update-config.jpg
然后我们启动客户端,观察打印的日志,如下图所示:
long-polling-cost-result.jpg
从打印出来的日志可以看出来,客户端足足等了29.5+s,才请求到服务端的结果。然后客户端得到服务端的结果之后,再做一些后续的操作,全部都执行完毕之后,在 finally 中又重新调用了自身,也就是说这个过程是一直循环下去的。
长轮询时修改配置
现在我们可以确定的是,客户端向服务端发起一次请求,最少要29.5s才能得到结果,当然啦,这是在配置没有发生变化的情况下。
如果客户端在长轮询时配置发生变更的话,该请求需要多长时间才会返回呢,我们继续做一个实验,在客户端长轮询时修改配置,结果如下图所示:
long-polling-cost-result-2.jpg
上图中红框中就是我在客户端一发起请求时就更新配置后打印的结果,