如何远程更新 Java 应用程序?

2022-09-01 14:35:21

我们有一个Java服务器应用程序,它可以在多台计算机上运行,这些计算机都连接到Internet,有些计算机位于防火墙后面。我们需要从中央站点远程更新 JAR 文件和启动脚本,而不会对应用本身造成明显中断。

该过程必须是无人值守且万无一失的(即,由于不合时宜的互联网中断,我们无法承受破坏应用程序的费用)。

过去,我们使用各种外部脚本和实用程序来处理类似的任务,但由于它们有自己的依赖项,因此结果更难维护且可移植性较差。在制作新东西之前,我想从社区获得一些意见。

有没有人已经找到了一个很好的解决方案?有什么想法或建议吗?

只是为了澄清:这个应用程序是一个服务器,但不是Web应用程序(这里没有web应用程序容器或WAR文件)。它只是一个自主的Java程序。


答案 1

你没有指定服务器应用程序的类型 - 我将假设你没有运行Web应用程序(因为部署WAR已经执行了你所谈论的事情,并且你很少需要Web应用程序来执行拉取类型更新。如果您正在谈论Web应用程序,以下讨论仍然可以适用 - 您只需为WAR文件而不是单个文件实现更新检查和乒乓球)。

你可能想看看jnlp - WebStart基于此(这是一种客户端应用程序部署技术),但我非常确定它可以定制为服务器类型的应用程序执行更新。无论如何,jnlp在提供描述符方面做得很好,这些描述符可用于下载所需JAR的必需版本...

关于这一点的一些一般想法(我们在同一存储桶中有几个应用程序,并且正在考虑自动更新机制):

  1. 考虑使用引导.jar文件,该文件能够在启动应用程序之前读取 jnlp 文件并下载所需/更新的 jar。

  2. 即使在应用程序运行时也可以更新JAR文件(至少在Windows上,这是最有可能对正在运行的文件进行锁定的操作系统)。如果您使用的是自定义类装入器,或者您有一堆可能随时装入或卸载的 JAR,则可能会遇到问题,但是如果您创建了防止这种情况的机制,那么覆盖 JAR 然后重新启动应用程序应该足以进行更新。

  3. 即使可以覆盖 JAR,你也可能需要考虑对库路径使用一种乒乓球方法(如果你还没有将应用启动器配置为自动读取 lib 文件夹中的所有 jar 文件并自动将它们添加到类路径中,那么这就是你真正想要做的事情)。以下是乒乓球的工作原理:

应用启动并查看 lib-ping\version.properties 和 lib-pong\version.properties,并确定哪个更新。假设 lib-ping 有一个更高版本。启动器搜索 lib-ping*.jar,并在启动期间将这些文件添加到 CP 中。当您进行更新时,您将jar文件下载到lib-pong中(或者如果您想节省带宽并且JAR实际上没有更改,则可以从lib-ping复制jar文件 - 不过,这很少值得!将所有 JAR 复制到 lib-pong 中后,您做的最后一件事就是创建 version.properties 文件(这样就可以检测并清除导致部分 lib 文件夹的中断更新)。最后,重新启动应用,引导程序会选取 lib-pong 是所需的类路径。

  1. 如上所述的乒乓球允许回滚。如果你设计得当,你可以让你的一个应用程序被你测试出来,然后永远不要改变那个检查,看看它是否应该回滚一个给定的版本。这样,如果您搞砸并部署了破坏应用程序的内容,则可以使版本无效。应用程序的这一部分只需要从错误的lib-*文件夹中删除version.properties文件,然后重新启动。保持这部分污垢简单很重要,因为它是您的故障安全。

  2. 您可以拥有 2 个以上的文件夹(例如,只需使用 lib-yymmdd 并清除除最新文件夹 5 个文件夹之外的所有文件夹,而不是 ping/pong)。这允许更高级(但更复杂!)的 JAR 回滚。


答案 2

你绝对应该看看OSGi,它是专门为这些情况(特别是对于嵌入式产品)而创建的,并且被大量公司使用。您可以在应用程序运行时更新jar“捆绑包”,添加和删除它们。我自己没有用过它,所以我不知道开源框架/服务器的质量,但这里有一堆有用的链接来帮助你入门:


http://www.osgi.org/Main/HomePage http://www.aqute.biz/Code/Bnd
http://blog.springsource.com/2008/02/18/creating-osgi-bundles/
http://blog.springsource.com/
http://www.knopflerfish.org/
http://felix.apache.org/site/index.html


推荐