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



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

因此:

符号链接x->路径/到/jar/version_1.0.0

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

现在我的问题是:

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

符号链接x->路径/到/jar/version_1.2.0

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

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

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

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

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

因此,当流程运行时,可能还没有加载某些类(例如,您为自当前运行开始以来尚未触发的非常特定的业务流"导入"了一些类(。因此,如果你要改变链接,有些东西可能会断开。

因此,如果你绝对需要提供"无需重启"的升级,你最好用不同的方式:

  • 同时启动两个JVM:一个运行旧进程,另一个运行新进程
  • 当新版本"准备就绪"时开始,开始将流量路由到它(好吧,这实际上取决于你的应用程序的实际功能(
  • 当你看到它按预期工作时,停止旧的应用程序

现在这实际上取决于您的应用程序的真实外观,您可能需要同步数据库的状态,同时用两个版本的应用程序执行请求,等等,所以在一般情况下,这可能是一件非常复杂的事情。

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

最新更新