当前位置: 首页 > 后端技术 > Java

一个硬链接引起的问题

时间:2023-04-01 21:53:08 Java

一个硬链接引起的问题问题背景最近,一个关于Fastjson的漏洞再次被曝光。作为修理工(哦不,是专业的软件工程师),又到了我们表演的时候了。我们的很多服务都使用了老版本的易受攻击的jar包。为了解决这个漏洞问题,我们决定使用新版本的jar包直接覆盖旧版本的有漏洞的jar版本。嘿嘿,要想把节目做好,三十六招缺一不可。问题现象解决方案确定了,下面开始工作。具体思路是:从环境中找出旧版本的jar包,然后备份到备份路径。这里的备份是为了支持回滚功能。然后将新版本的jar包复制到旧版本的jar包路径下。重启所有微服务,使jar包生效。代码逻辑如下图所示:对于所有旧版本jar包中的旧版本jar包;do备份旧版本的jar包,复制新版本的jar包覆盖旧版本的jar包done总体思路很简单,但是问题出在这个备份上。在实际测试过程中,发现在备份目录下,大部分版本的jar包都变成了新版本的jar包,而不是旧版本的jar包,如下图,在/下tmp/home/testuserfastjson-1.2.70.jar包的hash值其实和fastjson-1.2.83.jar包的hash值是一样的。一开始我一直以为是我的代码逻辑有问题,就反复检查。我先去掉新版本jar包覆盖旧版本jar包的逻辑,然后计算备份路径下的所有hash值,发现都是旧版本jar包,所以没有问题。但是一旦我添加了覆盖旧版本的jar包逻辑,备份的jar包版本就会发生变化。试了好几次,结果都一样,真是百思不得其解。困扰程序员的两大难题之一在脑海中浮现,为什么跑不起来?既然看不到,那只能用程序员的杀手锏,Debug。我计算了每次覆盖后备份目录下的jar的Hash值,发现执行第二个循环时备份目录下的jar文件已经变成了新版本。jar包文件。观察到这个现象后,我开始思考为什么会这样呢?第二个循环的逻辑明明和第一个循环的逻辑是一样的,为什么结果变了呢?那天搞了半天,也查不出是什么原因,脑子里乱成一团。没办法,明天继续做。第二天早上就来了,经过一夜的补血,思路又清晰了,感觉自己又好了。这时候我想起之前好像有人跟我说过,我们的jar包是由硬链接组成的。这让我想起一道经典的面试题:linux中的软链接和硬链接有什么区别?有什么不同?嗯……,想不起来了,书到时候,恨少了,默默流下无知的泪水。在网上找了一些文章看,从电脑屏幕下拿出压着的《鸟哥的 Linux 私房菜》复习。然后登录环境,查看环境中的旧版本jar包,发现确实是硬链接。为了演示这种情况,我在自己的环境中复现了这种情况,如下图:软链接和硬链接的区别可以参考网上的资料和书籍,这里不再赘述。对于我目前遇到的问题,我可以做一个不恰当的类比:硬链接就像照镜子。无论你做了什么改变,镜子里的你也会做出同样的改变。如上图所示,当我们更改/home/testuser目录下的fastjson-1.2.70.jar文件的内容时,/home/admin目录下的fastjson-1.2.70.jar文件的内容将会变得和它一样。知道了这个特性,我们结合代码来分析一下:已知条件:环境中有两个jar包文件:/home/testuser/fastjson-1.2.70.jar和/home/admin/fastjson-1.2.70。jar这两个jar包是硬链接关系推导:当我们执行第一个for循环到复制新版本jar包覆盖旧版本jar包的步骤时,其中一个jar包的版本paths会换成新版本的jar包,此时相当于/home/testuser/fastjson-1.2.70.jar和/home/admin/fastjson-1.2.70.jar这两个jar包都变成了新的jar包的版本当第二个for循环备份的是旧版本的jar包时,这次备份的实际上是新版本的jar包。这也是为什么第二次备份的jar包版本都是新版本的原因。对于所有旧版本jar包中的旧版本jar包;do备份旧版本的jar包,复制新版本的jar包,覆盖旧版本的jar包done解决方法知道了原因,我们来想想如何修改上面的代码?显然,备份和复制旧版本jar包这两个动作应该拆分成两个for循环来实现。这样的备份会在for循环中备份所有旧版本的jar包。如下代码所示:对于所有旧版本jar包中的旧版本jar包;dobackuptheoldversionofjarpackagedonefor旧版本jar包中的所有旧版本jar包;do复制新版本jar包done覆盖旧版本jar包问题的解决方法主要是理解硬链接的原理。说实话,这方面的知识我之前看过很多遍,每次看的时候都觉得自己看懂了,但是真正遇到问题的时候才发现自己根本不懂。通过这个问题的解决,我想我应该对硬链接有了一定的了解。其实在日常工作中,很多小问题其实都对应着一些知识点。如果我们能够搞清楚这些小问题,其实对我们真正理解和掌握这些知识会有很大的帮助。好了,今天就到这里吧,朋友们,我们下期再见!