26

问题:我有一个独立的 Java 应用程序(以下称为“代理”)作为服务在公司内部服务器上运行。它充当某些中央服务器的远程代理。随着代理部署在更多地方,管理它们变得越来越复杂。具体来说:推送更新很痛苦,因为它是一个相当手动的过程,并且访问有关代理运行环境的日志和其他信息是有问题的,使得调试变得困难。讨论中的服务器是无头和无人值守的,这意味着这必须是一个完全自动化的过程,没有人工干预,因此Java Web Start 不是一个可行的解决方案

建议的解决方案:定期让代理电话回家(到中央服务器)以提供代理状态并检查更新。

我对解决该问题的其他建议解决方案持开放态度,但我已经有了“状态和自我更新”想法的工作原型,这就是这个问题的重点。

我想出的实际上是一个单独的项目,它充当代理的包装器。包装器定期通过 HTTP 调用中央服务器以检查代理的更新版本。找到更新后,它会下载新版本,关闭正在运行的代理,然后启动新代理。如果这似乎是一个奇怪或迂回的解决方案,这里有一些值得注意的其他注意事项/约束:

  1. 当包装器获得新版本的代理时,可能会有新的 JAR 依赖项,这意味着类路径发生了变化,这意味着我可能想要生成一个单独的 Java 进程,而不是摆弄 ClassLoaders 并冒着永久代内存泄漏的风险,这需要人工干预——这正是我想要摆脱的。这就是为什么我最终使用了一个单独的“包装”流程来管理原型中的代理更新。
  2. 部署代理的一些服务器资源有限,因此任何解决方案都需要降低 CPU 和内存使用率。这让我想要一个不涉及启动新 JVM 的解决方案,并且反对拥有一个单独的包装进程。
  3. 该代理已经部署到 Windows 和 RHEL 服务器,因此解决方案必须是跨平台的,尽管我不会有问题在批处理和 bash 脚本中复制合理数量的过程以使事情顺利进行。

问题:如前所述,我想知道如何制作一个自我更新的 Java 应用程序。更具体地说,是否有任何框架/库可以帮助我解决这个问题?有这方面经验的大神可以指点一下吗?

4

5 回答 5

4

如果您的应用程序是基于 OSGi 的,您可以让 OSGi 为您处理包更新。它类似于您建议的包装器方法,因为 OSGi 容器本身就是“包装器”,其中一些不会被更新。这是对此的讨论

于 2012-04-20T23:09:31.370 回答
4

不同的解决方案:使用(并付费)install4j。在此处查看自动更新功能

于 2012-04-20T23:12:25.990 回答
3

不需要包装器(节省内存)或 java web start(对您的应用程序添加更多限制),只需让应用程序中的线程定期检查更新(例如从云)并下载更新(如果可用),然后在您的代码中编写这两个调用应用:

  1. 启动一个 shell 脚本 (.sh.cmd) 以更新您的工件并在脚本暂停几秒钟后启动您的应用程序(以避免同时有两个应用程序实例)。
  2. 终止您的应用程序(第一个实例)

该脚本可以覆盖所需的工件并重新启动您的应用程序。

请享用 !

于 2015-06-18T02:18:12.877 回答
2

看看 Java Web Start。

它是自... 1.5 以来一直是Java 一部分的技术?也许1.4?并允许通过 Web 浏览器部署和安装基于 Java 的独立应用程序。它还使您能够始终运行最新的应用程序。

http://www.oracle.com/technetwork/java/javase/overview-137531.html

http://en.wikipedia.org/wiki/JNLP#Java_Network_Launching_Protocol_.28JNLP.29

另请参阅此问题:向 Java Swing 应用程序添加自我更新功能的最佳方法是什么?

于 2012-04-20T03:52:24.387 回答
0

似乎Webstart是目前唯一内置的方法。

于 2012-04-20T03:51:34.037 回答