问题描述
因此,我正在考虑为我的进程设置部署脚本,以指向一个符号链接,该符号链接指向我的应用程序的jar的最新版本。
所以:
符号链接x-> /path/to/jar/version_1.0.0
现在,用于我的进程的脚本将在其启动脚本中引用symlink x来加载jar。
现在我的问题是:
鉴于该进程仍在运行...我可以安全地将符号链接x更新为:
符号链接x-> /path/to/jar/version_1.2.0
我不会删除/path/to/jar/version_1.0.0,因此它仍将保留在主机上。
我担心的是,该过程可能会开始从新的符号链接路径而不是脚本最初运行的/path/to/jar/version_1.0.0路径加载尚未在内存中的jar。
解决方法
这全取决于您何时更新符号链接和何时加载jar。 创建符号链接时,会分配一个新的索引节点,这意味着符号链接是与原始文件不同的实体。
更新(再次取消链接+链接)符号链接时,它基本上会创建一个新的索引节点。因此,如果您的第一个符号链接已经被调用和使用,则除非再次调用,否则将不再使用新的符号链接。尽管它们具有相同的路径,但是它们在文件系统级别上是不同的资源。
,总的来说,我认为您的担心是正确的。 JVM在真正需要时动态加载类。
因此,有可能在流程运行时尚未加载某些类(例如,针对自当前运行开始以来尚未触发的非常特定的业务流程“导入”一些类)。 因此,如果您更改链接,则可能会损坏某些东西。
因此,如果您绝对需要“不重启”升级,则最好以其他方式进行升级:
- 同时启动两个JVM:一个将运行旧进程,另一个将运行较新进程
- 在新版本“就绪”时开始路由流量(好吧,这实际上取决于您的应用程序实际执行的操作)
- 当您看到它运行正常时,请停止旧应用。
现在,这实际上取决于您的应用程序的外观,您可能需要同步数据库的状态,同时使用两个版本的应用程序执行请求,依此类推,因此在一般情况下,可能是一件非常复杂的事情。
一些现代的高级工具(如kubernetes)可以在DevOps领域提供帮助,但是您仍然必须了解应用程序中到底发生了什么,以获得最佳结果。