在进程运行时将符号链接更新到 jar 是不是安全?

Posted

技术标签:

【中文标题】在进程运行时将符号链接更新到 jar 是不是安全?【英文标题】:Is it safe to update a symlink to a jar while the process is running?在进程运行时将符号链接更新到 jar 是否安全? 【发布时间】:2020-12-11 06:49:47 【问题描述】:

所以我正在考虑为我的进程设置我的部署脚本以指向一个符号链接,该符号链接指向我的应用程序的最新版本的 jar。

所以:

符号链接 x -> /path/to/jar/version_1.0.0

现在,我的进程的脚本将加载 jar,在其启动脚本中引用符号链接 x。

现在我的问题是:

鉴于进程仍在运行...我可以安全地将符号链接 x 更新为:

符号链接 x -> /path/to/jar/version_1.2.0

我不会删除 /path/to/jar/version_1.0.0,因此它仍会保留在主机上。

我担心该进程可能会开始从新的符号链接路径而不是脚本首先运行的 /path/to/jar/version_1.0.0 路径加载尚未在内存中的 jar。

【问题讨论】:

【参考方案1】:

这完全取决于您何时更新符号链接以及何时加载您的 jar。 创建符号链接时,会分配一个新的 inode,这意味着您的符号链接与原始文件是不同的实体。

当您更新(再次取消链接 + 链接)符号链接时,它基本上会创建一个新的 inode。因此,如果您的第一个符号链接已被调用并使用,则将不再使用新的符号链接,除非再次调用。尽管它们具有相同的路径,但它们在文件系统级别是不同的资源。

【讨论】:

这是否意味着这样做不安全?因为这意味着如果我的应用程序需要加载尚未在内存中的 jar,并且我更新了符号链接,它最终会转到比它第一次运行时更新的位置? 如果 jars 已经加载,那么更新符号链接是安全的。如果它们不是,尽管您的进程已启动,那么将加载新的进程。这完全取决于您何时实际调用符号链接以及它们是如何处理的。 blog.moertel.com/posts/… 那怎么办 - 这会阻止它这样做吗? 最好是测试你的脚本。仅基于假设很难说它的行为方式。也许一些有适当延迟的测试会提供更多的见解。【参考方案2】:

总的来说,我认为您的担忧是正确的。 JVM 在真正需要时动态加载类。

因此,当流程运行时,可能还没有加载某些类(例如,您“导入”了一些自当前运行开始以来尚未触发的非常特定的业务流程的类)。 因此,如果您更改链接,则可能会出现某些问题。

因此,如果您绝对需要提供“无需重新启动”的升级,您最好采用不同的方式:

同时启动两个 JVM:一个运行旧进程,一个运行新进程 在新版本“准备就绪”时开始将流量路由到它(好吧,这真的取决于您的应用程序的实际用途) 当您看到它按预期工作时 - 停止旧应用程序。

现在这实际上取决于您的应用程序的实际外观,您可能需要同步 DB 的状态,同时使用两个版本的应用程序执行请求等等,所以在一般情况下做起来可能很复杂。

一些现代高级工具(如 kubernetes)可以在 DevOps 领域提供帮助,但您仍然必须了解应用程序中究竟发生了什么才能获得最佳结果。

【讨论】:

谢谢你....最好回到绘图板:(我不能像你描述的那样进行现场直播。我下一个最好的选择是在脚本中有符号链接然后在运行时更改脚本,尽管这有其自身的危险

以上是关于在进程运行时将符号链接更新到 jar 是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

在运行时将jar添加到类路径

在与 Rust 中的本机库链接时将符号公开给动态链接器

可以将IDEA配置为构建jar并从中运行测试吗?

无法启动“软件更新程序”:无法执行子进程/usr/bin/update-manager(符号链接链接级别太多)[关闭]

在使用 jar 选项时将作业提交到不同的公平调度程序池

动态链接及静态链接