我们有一个Java服务器应用程序,它运行在许多计算机上,都连接到Internet,一些在防火墙后面.我们需要从中央站点远程更新JAR文件和启动脚本,而不会对应用程序本身造成明显的中断.
这个过程必须是无人值守和万无一失的(即我们无法承受因不合时宜的互联网中断而破坏应用程序).
在过去,我们使用各种外部脚本和实用程序来处理类似的任务,但由于它们有自己的依赖关系,因此结果难以维护且便于携带.在制作新内容之前,我想从社区获得一些意见.
有人找到了一个很好的解决方案吗?有任何想法或建议吗?
只是为了澄清:这个应用程序是一个服务器,但不适用于Web应用程序(此处没有webapp容器或WAR文件).它只是一个自治的Java程序.
您没有指定服务器应用程序的类型 - 我将假设您没有运行Web应用程序(因为部署WAR已经完成了您正在谈论的内容,并且您很少需要Web应用程序来执行拉动类型如果您正在讨论Web应用程序,以下讨论仍然适用 - 您只需实现WAR文件的更新检查和乒乓而不是单个文件.
您可能想看看jnlp - WebStart基于此(这是一种客户端应用程序部署技术),但我非常确定它可以针对服务器类型应用程序执行更新而定制.无论如何,jnlp在提供可用于下载所需JAR所需版本的描述符方面做得相当不错......
对此有一些一般性的想法(我们在同一个桶中有几个应用程序,并且正在考虑自动更新机制):
考虑使用bootstrap.jar文件,该文件能够在启动应用程序之前读取jnlp文件并下载所需/更新的jar文件.
即使在应用程序运行时也可以更新JAR文件(至少在Windows上,这是最有可能对运行文件进行锁定的操作系统).如果您使用自定义类加载器,或者您有一堆可能随时加载或卸载的JAR,您可能遇到问题,但如果您创建机制来防止这种情况,那么覆盖JAR然后重新启动应用程序应该是足以更新.
尽管可以覆盖JAR,但您可能需要考虑使用ping路径的ping-pong方法(如果您尚未将应用程序启动器配置为自动读取lib文件夹中的所有jar文件并将其添加到类路径自动,那就是你真正想做的事情).以下是乒乓球的工作原理:
应用程序启动并查看lib-ping\version.properties和lib-pong\version.properties并确定哪个更新.假设lib-ping有更高版本.启动程序搜索lib-ping*.jar并在启动期间将这些文件添加到CP.当你进行更新时,你可以将jar文件下载到lib-pong中(或者如果你想节省带宽而从lib-ping复制jar文件,而JAR实际上并没有改变 - 尽管这很费劲!).将所有JAR复制到lib-pong后,最后要做的就是创建version.properties文件(这样就可以检测并清除导致部分lib文件夹的中断更新).最后,您重新启动应用程序,并且bootstrap选择lib-pong是所需的类路径.
如上所述的乒乓球允许回滚.如果你正确地设计它,你可以拥有一个你测试的应用程序,然后永远不会更改检查,看它是否应该回滚给定的版本.这样,如果您搞砸并部署破坏应用程序的内容,则可以使版本无效.应用程序的这一部分只需要从坏的lib-*文件夹中删除version.properties文件,然后重新启动.重要的是要保持这部分简单,因为这是你的安全故障.
您可以拥有2个以上的文件夹(而不是ping/pong,只需要lib-yyyymmdd并清除除最新的5之外的所有文件夹).这允许更高级(但更复杂!)回滚JAR.