建议部署 war 文件与嵌入容器的可执行 jar

目前 Java 领域似乎有一种趋势,即从以 war 文件(或 ear 文件)的形式将 Java Web 应用程序部署到 java servlet 容器(或应用服务器) ,转而将应用程序打包为可执行 jar,并嵌入 servlet/HTTP 服务器(如 jetty)。我的意思是,更新的框架正在影响新应用程序的开发和部署,而不是应用程序如何交付给最终用户(因为,例如,我明白为什么 Jenkins 使用嵌入式容器,非常容易抓取和使用)。采用可执行 jar 选项的框架示例: DropWizard 弹簧靴演奏(它不在 servlet 容器上运行,但是 HTTP 服务器是嵌入式的)。

我的问题是,在一个环境中,我们已经将我们的应用程序(到目前为止主要是 Struts2)部署到单个 tomcat 应用程序服务器上,如果我们计划使用嵌入式容器方法,需要做哪些更改、最佳实践或考虑因素?目前,我们有大约10个自主开发的应用程序运行在单个 tomcat 服务器上,并且适用于这些小型应用程序 能够在一台服务器上共享资源并进行管理是很好的。我们的应用程序不打算分发给最终用户,以便在他们的环境中运行。然而,如果我们决定利用一个更新的 Java 框架,这种方法是否应该改变?云部署(例如 Heroku)的使用越来越多,是否刺激了向可执行 jar 的转变?

如果您有过在一个应用服务器上以 Play 部署方式管理多个应用程序的经验,而不是传统的 war 文件部署方式,请与我们分享您的见解。

17081 次浏览

An interesting question. This is just my view on the topic, so take everything with a grain of salt. I have occasionally deployed and managed applications using both servlet containers and embedded servers. I'm sure there are still many good reasons for using servlet containers but I will try to just focus on why they are less popular today.

Short version: Servlet containers are great to manage multiple applications on a single host but don't seem very useful to manage just one single application. With cloud environments, a single application per virtual machine seems preferable and more common. Modern frameworks want to be cloud compatible, therefore the shift to embedded servers.


So I think cloud services are the main reason for abandoning servlet containers. Just like servlet containers let you manage applications, cloud services let you manage virtual machines, instances, data storage and much more. This sounds more complicated, but with cloud environments, there has been a shift to single app machines. This means you can often treat the whole machine like it is the application. Each application runs on a machine with appropriate size. Cloud instances can pop up and vanish at any time which is great for scaling. If an application needs more resources, you create more instances.

Dedicated servers on the other hand usually are powerful but with a fixed size, so you run multiple applications on a single machine to maximize the use of resources. Managing dozens of application - each with their own configurations, web servers, routes and connections etc. - is not fun, so using a servlet container helps you to keep everything manageable and yourself sane. It is harder to scale though. Servlet containers in the cloud don't seem very useful. They would have to be set up for each tiny instance, without providing much value since they only manage a single application.

Also, clouds are cool and non-cloud stuff is boring (if we still believe the hype). Many frameworks try to be scalable by default, so that they can easily be deployed to the clouds. Embedded servers are fast to deploy and run so they seem like a reasonable solution. Servlet containers are usually still supported but require a more complicated set up.

Some other points:

  • The embedded server could be optimized for the framework or is better integrated with the frameworks tooling (like the play console for example).
  • Not all cloud environments come with customizable machine images. Instead of writing initialization scripts to download and set up servlet containers, using dedicated software for cloud application deployments is much simpler.
  • I have yet to find a Tomcat setup that doesn't greet you with a perm gen space error every few redeployments of your app. Taking a bit longer to (re-)start embedded servers is no problem when you can almost instantly switch between staging and production instances without any downtime.
  • As already mentioned in the question, it's very convenient for the end user to just run the application.
  • Embedded servers are portable and convenient for development. Today everything is rapid, prototypes and MVPs need to be created and delivered as fast as possible. No one wants to spend too much time setting up an environment for every developer.