Java Web应用程序在Servlet容器中与独立运行的区别

32

相比构建一个带有内置Web服务器的独立Java应用,然后在反向代理后运行它,构建一个小型Java Web应用程序以在Servlet容器(如Tomcat)中运行有哪些优点?

我已经使用Java玩了一年左右。我注意到启动Tomcat需要时间,并且由于类加载器问题,不总是能够进行热重载。从配置和RESTful设计的角度来看,Servlet API 对我来说似乎有些复杂(它并没有完全支持RESTful设计)。

另一方面,我注意到我的集成开发环境(IDE)可以以闪电般的速度编译和运行独立应用程序。配置Apache进行反向代理非常容易,而嵌入式Jetty似乎可以处理我能够投入它的一切。当我可以使用Restlet、Wicket等技术时,我就不需要Servlet了。因为应用程序未集成到庞大的应用服务器中,所以我能更好地了解它的工作原理,这使我感到很有力量。堆栈跟踪更短。下载大小更小。终端用户配置更容易。我猜测性能可能会更好,因为涉及的软件层数更少。

但是,我想起了那句话:听起来太美好的东西通常都是不真实的。所以我的问题是:为什么我不想让我的Web应用程序独立运行?Servlet容器为我和/或我的终端用户提供了什么我们真正需要但却不知道的东西?

6个回答

14

这里有两个单独的问题:

  1. 我应该使用嵌入式服务器还是部署到容器中?

    我认为这两种方式并没有太大的区别。使用Jetty服务器启动程序需要编写稍微多一些的代码,但配置可以更加便捷地进行编程。尽管Web应用程序的IDE支持配置和部署正在变得越来越好,但仍然比独立应用程序差(这在某种程度上是定义上的,因为有一组超集需要支持)。

    另一方面,应用服务器提供了一些很好的优点,如内置管理、作为服务运行的内置功能等。

    甚至可以使用混合方法:在本地使用嵌入式服务器进行开发,然后在生产中将其部署到容器中。但这有点奇怪:如果你费劲地制作一个正确的WAR文件,那么IDE应该能够充分处理适当的容器部署。

    顺便说一下,如果你在热重载方面遇到了问题,那很奇怪;Tomcat不应该有这个问题,除非你遇到了一些奇怪的边角情况...

  2. 我应该使用Servlet API吗?

    这与第一点无关。你完全可以嵌入Jetty并实现Servlets。你也可以通过ServerServlet在Tomcat中使用Restlet API http://www.restlet.org/documentation/1.0/faq#02

    我个人认为Servlet API相当直观。你会得到很好的并发性和状态管理等有益特性。我不太清楚RESTful设计不支持是什么意思,但如果Restlets更好地满足了你的需求,那就用它吧...


5
Embedded Jetty可以是一个不错的选择,如果您不需要完整的Servlet堆栈。与Tomcat不同,Jetty使得轻松摆脱您不使用的部分(JSP,JNDI等)。
另一方面,编写自己的HTTP服务器是一个可怕的想法。当然,编写处理基本请求的内容很容易。但很快你会发现,一些客户端在使用它时遇到问题,因为它不支持完整的协议规范;或者当有超过几百个用户时,它会崩溃;或者存在漏洞,允许马来西亚的某个孩子炸毁你的打印机。所以不要重复造轮子。
至于您抱怨Servlet API不支持RESTful设计 - 您错过了重点,它从未旨在这样做。但是有很多REST库可以在Servlet API上运行。

4
一个嵌入式Jetty也是一个Servlet容器。我假设你的应用程序包括一个web.xml,在其中定义了一个wicket过滤器/Servlet、RESTlet Servlet及其映射(至少)。所以,即使你将它嵌入,也不能摆脱Servlet API(或Servlet容器),但你可以尽可能地隐藏它在你自己的框架和一些main()方法中。RESTlet(或Jersey或任何JAX-RS实现)以及Spring MVC都基于Servlets,因此Servlet API支持REST非常好,我想说。

P.S. 这两种方法并不互斥。在开发过程中,你可以很好地使用Jetty,然后将你的war部署到某个(非嵌入式)容器进行QA /生产。或者……如果真的适合你的需求,就坚持使用Jetty进行生产。


0

进程内Servlet容器是在Web服务器的JVM内部工作的容器,它们提供良好的性能但可扩展性较差。

进程外容器是在Web服务器之外的JVM中工作的容器。性能较差但可扩展性更好。在进程外容器的情况下,Web服务器和容器通过使用IPC等一些标准机制进行通信。

除了这些类型的容器之外,还有第三种类型,即独立的Servlet容器。它们是Web服务器的一个组成部分。


0

Servlet容器通常提供许多有用的功能,如自动会话管理、热部署、故障转移和集群框架等。当然,这取决于容器,但有时这些工具非常有用。有时它们也不是。

编辑:刚注意到您关于热重载的评论。是的,有时容器存在漏洞并且很难使用,它们都倾向于有自己的怪癖。尽管如此,有时它们确实提供了一些非常好的东西。


-1

如果您在热部署方面遇到问题,很可能是因为您没有清理外部连接或其他资源。为了处理这个问题,通常您需要实现一个监听器,让您知道何时启动或停止某些内容。

您应该在您的 WAR 文件中实现类似以下代码(适用于 Tomcat 6):

public class MyTomcatInitCleanupListener implements ServletContextListener
{
    @Override
    public void contextInitialized(ServletContextEvent arg0)
    {
        super.contextInitialized(arg0);
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0)
    {
        super.contextDestroyed(arg0);
    }
}

对于Tomcat 7+,你可以在Google上搜索“Tomcat生命周期监听器”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接