Maven - 部署大型战争文件

发布于 2024-10-03 02:12:41 字数 1225 浏览 0 评论 0原文

这个问题有点类似于这个 部署大型 *.war 的最佳方式到 tomcat 所以首先阅读它很好,但是继续阅读我的 q,最后会有所不同...

使用 maven 2 我的 war 文件非常大(60M)。我将它们部署到一组 tomcat 服务器上,仅复制文件就花费了太长时间(每次战争大约 100 万)。

除此之外,我添加了一个 RPM 层,它将把 war 打包到 RPM 文件中(使用 maven 的 rpm 插件)。当 RPM 在目标机器上执行时,它将进行清理,“安装”war(只需复制它),停止并启动 tomcat(这就是我们在这里做事的方式,没有热部署)并在地方。这一切都很好。
但问题是 RPM 文件太大且复制速度慢。占据几乎整个空间的自然是war文件。

我还没有看到任何现成的解决方案,所以我正在考虑自己实现一个,所以我将在下面描述它,这个描述希望有助于解释问题领域。我很高兴听到您对计划解决方案的想法,最好向我指出其他现有的解决方案和随机提示。

war 文件包含:

  1. 应用程序 jars
  2. 第 3 方 jar
  3. 资源(属性文件和其他资源)
  4. WEB-INF 文件,例如 JSP、web.xml、struts.xml 等

大部分空间被#2(第 3 方 jar)占用。< br> 第 3 方 jar 也安装在我们公司的内部 Nexus 服务器上,因此我可以利用它。

您现在可能已经猜到了,因此计划是创建精简战争,其中仅包含应用程序 jar(由我公司编写的)、资源和 WEB-INF 内容,并向将复制的 RPM 安装脚本添加智能性需要时第 3 方 jars。
RPM 允许您在安装之前或之后运行任意脚本,因此计划是在构建 war 时使用 mvn 编写第 3 方依赖项列表,并将其作为资源添加到 RPM,然后在安装 RPM 时,RPM 安装脚本将运行在所需的第 3 方 jar 列表中,仅当新 jar 尚不存在时才从 Nexus 下载。
如果不使用 jar,RPM 必须将其删除。
RPM 还必须要么重建 tomcat 的战争来爆炸它,要么将第 3 方 jar 添加到 common/lib 或类似的东西,尽管我们每个 tomcat 有一些网络应用程序,所以从这个意义上来说它会让事情变得复杂。也许会自行爆炸 jar,然后将第 3 方 jar 复制到 WEB-INF/lib

您的输入表示赞赏:)

This question is somewhat similar to this one Best way to deploy large *.war to tomcat so it's a good read first, but keep on reading my q, it's different at the end...

Using maven 2 my war files are awfully large (60M). I deploy them to a set of tomcat servers and just copying the files takes too long (it's about 1m per war).

On top of that I added an RPM layer that'll package the war in an RPM file (using maven's rpm plugin). When the RPM is executed on the target machine it'll cleanup, "install" the war (just copy it), stop and start the tomcat (that's how we do things here, no hot deploys) and set up a proper context file in place. This all works fine.
The problem, however, is that the RPM files are too large and slow to copy. What take almost eh entire space is naturally the war file.

I haven't seen any off-the-shelf solution so I'm thinking of implementing one myself so I'll describe it below and this description will hopefully help explain the problem domain. I'll be happy to hear your thought on the planned solution, and better yet point me at other existing solutions and random tips.

The war files contain:

  1. Application jars
  2. 3rd party jars
  3. resources (property files and other resources)
  4. WEB-INF files such as JSPs, web.xml, struts.xml etc

Most of the space is taken by #2, the 3rd party jars.
The 3rd party jars are also installed on an internal nexus server we have in the company so I can take advantage of that.

You probably guessed that by now, so the plan is to create thin wars that'll include only the application jars (the ones authored by my company), resources and WEB-INF stuff and add smartness to the RPM install script that'll copy the 3rd party jars when needed.
RPM allows you to run arbitrary scripts before or after installation so the plan is to use mvn write a list of 3rd party dependencies when building the war and add it as a resource to the RPM and then when installing an RPM the RPM installation script will run over the list of required 3rd party jars and download the new jars from nexus only if they don't exist yet.
The RPM will have to delete jars if they are not used.
The RPM will also have to either rebuild the war for tomcat to explode it or add the 3rd party jars to common/lib or something like that although we have a few web-apps per tomcat so it'll make things complicated in that sense. Maybe explode the jar by itself and then copy the 3rd party jars to WEB-INF/lib

Your input is appreciated :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

思念满溢 2024-10-10 02:12:41

我们在目标机器上有一个目录,其中包含我们正在使用的所有第三方 jar(大约 110Mb)。这些 jar 使用包含其版本号的命名编码约定(asm-3.2.jar、asm-2.2.3.jar ...)。添加第三方的新版本时,我们不会删除旧版本。

部署时,我们的 jar 文件仅包含我们在构建中编译的业务逻辑类和资源(无第三方)。类路径在 jar 清单 中定义,我们在其中选择哪个它应该在运行时使用第三方。我们正在使用 ant 来实现这一点,没有涉及 Maven,并且我们的系统中有超过 25 种类型的服务(非常“soa”,尽管我不喜欢这个过于流行的词)。该业务逻辑 jar 是启动进程时 jvm 类路径中的唯一 jar,并且它也由我们的代码存储库修订号进行版本控制。如果您返回到可能使用较旧的第三方 jar 的旧版本(回滚)代码,它仍然可以工作,因为我们不会删除旧的 jar。新的第三方 jar 应该在使用它们的业务代码之前传播到生产计算机。但一旦他们到达那里,他们就不会在每次部署中被重新推动。

总的来说,我们倾向于简单性(即不是 OSGi)并且我们不使用 Maven。

We have a directory on the target machines with all third party jars we're using (about 110Mb). The jars are using a naming coding convention that includes their version number (asm-3.2.jar, asm-2.2.3.jar ...). When adding a new version of a third party we don't delete the older version.

When deploying, our jar files contains only business logic classes and resources we compile in the build (no third party). The classpath is defined in the jar manifest where we cherry pick which third party it should be using at runtime. We're doing that with ant, no maven involved and we have more then 25 types of services in our system (very "soa" though I dislike this over buzzed word). That business logic jar is the only jar in the jvm classpath when starting the process and it is also versioned by our code repo revision number. If you go back to older revision (rollback) of our code that might be using an older third party jar its still going to work as we don't remove old jars. New third party jars should be propagated to production machines before the business code that uses them does. But once they're there they're not going to be re-pushed on each deployment.

Overall we lean towards simplicity (i.e. not OSGi) and we don't use Maven.

白云不回头 2024-10-10 02:12:41

我建议反对你提出的计划。听起来好像有很多移动部件,当问题出现时可能很难测试和/或诊断问题。

我们没有“大型”WAR 的问题,但我们确实有这样的问题:大多数 WAR 的类路径都需要完全相同的第 3 方库。我们提出的解决方案(效果很好)是利用 OSGi 模块化地构建我们的应用程序。我们使用 Felix 作为在 Tomcat 内部运行的 OSGi 容器。然后,我们将所有依赖项/库部署到 Felix 一次。然后我们部署“瘦”WAR,它只是通过从它关心的包中导入它需要的包来引用 OSGi 依赖项。

这还有其他一些优点:

  • 在旧版本运行时部署新版本的 OSGi 包不是一个问题,不会造成停机(类似于热部署)。
  • 如果您需要升级依赖项之一(例如 Spring 2.5 -> 3.0),则只需升级 OSGi 中运行的 Spring 包即可;如果 API 没有更改,则无需交付(或打包)新的 WAR。这一切都可以(再次)在实时运行的 OSGi 容器上完成,无需关闭任何内容。
  • OSGI 保证您的包不会共享类路径。这有助于保持代码简洁,因为每个 WAR 只需要了解它所关心的内容。

将 WAR 设置为“OSGi 就绪”并非易事,但有详细记录。尝试查看如何开始使用 OSGi 或仅 Google 获取第 3 方教程。相信我,最初的投资将为您节省大量时间,并在未来解决许多令人头疼的问题。

如果可能的话,最好不要重新发明模块化轮子

I would advise against your proposed plan. It sounds like a lot of moving pieces that are likely hard to test and/or diagnose problem when they arise.

We don't have the problem of "large" WARs but we do have the problem that most of our WARs all need the exact same 3-rd party libraries on their classpath. The solution we went forth with (that has worked very well) was to utilize OSGi to build our application modularly. We use Felix as our OSGi container which runs inside of Tomcat. We then deploy all of our dependencies/libraries to Felix once. Then we deploy "thin" WARs which just reference OSGi dependencies by Importing the packages it needs from the bundles it cares about.

This has a few other advantages:

  • Deploying new versions of OSGi bundles while the old ones are running is not an issue which allows for no downtime (similar to hot deploy).
  • If you need to upgrade one of your dependencies (e.g. Spring 2.5 -> 3.0), you only need to upgrade the Spring bundle running in OSGi; no need to deliver (or package) new WARs if the APIs did not change. This can all (once again) be done on a live running OSGi container, no need to turn anything off.
  • OSGI guarantees your bundles do not share classpaths. This helps keep your code cleaner because each WAR only needs knowledge of what it cares about.

Setting up your WARs to be "OSGi ready" is not trivial but it is well documented. Try checking out How to get started with OSGi or just Google for 3rd party tutorials. Trust me, the initial investment will save you much time and many headaches in the future.

It is probably best not to re-invent the modularity wheel if possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文