若有收获,请记得分享和转发哦
之前遇到个文件监听变更的问题,刚好这周末有空研究了一番,整理出来分享给大家。
从一次故障说起
我们还是从故障说起,这样更加贴近实际,也能让大家更快速理解背景。
有一个下发配置的服务,这个配置服务的实现有点特殊,服务端下发配置到各个服务的本地文件,当然中间经过了一个agent,如果没有agent也就无法写本地文件,然后由client端的程序监听这个配置文件,一旦文件有变更,就重新加载配置,画个架构图大概是这样:
今天的重点是文件的变更该如何监听(watch),我们当时的实现非常简单:
单独起个线程,定时去获取文件的最后更新时间戳(毫秒级)
记录每个文件的最后更新时间戳,根据这个时间戳是否变化来判断文件是否有变更
从上述简单的描述,我们能看出这样实现有一些缺点:
无法实时感知文件的变更,感知误差在于轮询文件最后更新时间的间隔
精确到毫秒级,如果同一毫秒内发生2次变更,且轮询时刚好落在这2次变更的中间时,后一次变更将无法感知,但这概率很小
还好,上述两个缺点几乎没有什么大的影响。
但后来还是发生了一次比较严重的线上故障,这是为什么呢?因为一个JDK的BUG,这里直接贴出罪魁祸首:
jdk_11.0.6
每隔一段时间(默认为10s)去poll下,这个poll干了什么?代码太长,我截出关键部分: