使用Web服务器和应用服务器的Java EE应用程序

17

Java EE应用程序是否需要Web服务器(如SUN Java Web Server)来处理servlet/jsp请求并转发到应用服务器(如IBM WebSphere或BEA WebLogic)?

既然应用服务器也能够处理这样的servlet/jsp,那么是否有必要使用Web服务器呢?

这种服务器架构的优缺点是什么?

3个回答

40

Apache TomcatJettySun Java System Web Server 只是Java Web(Servlet)容器,意味着它们只能执行Servlets/JSP - 它们不提供完整的Java EE API堆栈。

因此,它们只能部署.war文件,而不能部署.ear(这也包括带有EJB的.jar模块),并且不支持一些Java EE API,如JSF或CDI等。或其他功能/API。 需要注意的是,自Java EE6以来,.war文件可以包含EJBs有关.war.ear差异的更多信息


每个Java EE服务器都有一个Web容器+ EJB容器。 (您可以在此处此处看到Tomcat和Jetty并未声称自己是JavaEE服务器,只是Servlet(Web)容器。)

JBoss应用服务器使用JbossWeb(一个Apache Tomcat分支)作为其Web容器。其EJB容器是JBoss(除了“JBoss EJB容器”之外,它们没有单独的名称)。

其他服务器(IBM WebSphere、Oracle/BEA WebLogic、TomEE、Glassfish)也都有它们自己的Web容器+EJB容器。

TomEE显然使用Apache Tomcat作为其Web容器。 Glassfish也使用Apache Tomcat的分支。(是的,Apache Tomcat似乎非常受欢迎 :)

在下面的讨论中,每当出现Tomcat时,你可以用“Web容器”来替换;每当出现JBoss时,你可以用“完全能力的Java EE服务器”来替换。 (我使用产品名称是为了清晰明了。)

JavaEE Server Containers

图片来源:Java EE教程。

使用Java Web服务器(如Tomcat)处理Servlet/JSP调用并将更复杂的请求转发到应用程序服务器(如JBoss或IBM WebSphere或BEA WebLogic)有何(不)优势?

从功能角度来看,没有有效的增益

如果您将Tomcat放置在JBoss之前,实际上是将Tomcat放置在JBossWeb(Web容器,因此是每个Web应用程序的入口)之前,它始终位于JBoss的EJB容器之前。如果我们谈论功能,那只是多余的,因为我们拥有两次提供相同服务的机会。

切换实现者或群集能力

如果他们仅使用JBoss的EJB容器,则在JBoss之前放置Tomcat可能是有意义的:在这种情况下,选择是切换Web容器实现者。

此外,如果Tomcat位于不同的网络节点上(或多个Tomcat/节点),则可以应用群集能力(否则无法应用,因为JBossWeb和JBoss通常被视为一个并因此在同一台机器上运行)。

提供静态内容和安全问题

非常普遍的是将Web服务器(如Apache HTTPD或IIS)放置在Java Web容器之前。这样做有两个主要动机:

  • 让HTTPD服务器提供静态内容(例如图片),并将其余内容转发到Java Web容器。这样做是因为Web服务器通常更好地优化了提供静态内容的任务。
  • 安全性:只暴露DMZ中的HTTPD。可以在DMZ中设置一个Apache HTTPD,并使其仅简单地转发所有请求到Web容器(Tomcat等)和JavaEE服务器(JBoss等)。

如果想要增加安全性,就没有必要在DMZ中使用Web容器:如果它正在提供应用程序(也就是部署了.war文件),那么这些应用程序仍然“有漏洞”;如果它只是转发请求/响应,则Apache HTTPD是更好的选择!


1
其他符合Java EE标准的服务器包括GlassfishTomEE - Menno
@optimus 我在回答中澄清了安全问题。如果您需要更多细节,请告诉我,我有印象您正在收集事实以便在公司谈论此事。我也会因为那种情况而感到受到冒犯,所以很高兴能够帮助! - acdcjunior
“Apache Tomcat [...] 实现 Java EE web profile” - 这是不正确的。它们只是 Servlet 容器。Web Profile 是另一回事。 - Arjan Tijms
1
@acdcjunior提到在应用服务器前使用Web服务器的最后一点是一个好建议。我应该强调,这是许多语言的Web服务器绝对标准做法- Java、Python、Ruby等。Web服务器有时被称为代理、反向代理、前端服务器,或者有时也被称为负载均衡器(如果它还执行负载均衡)。有许多原因支持这个好主意,包括安全性、稳定性、性能和可管理性,但现在不是深入讨论它们的时候! - Tom Anderson
1
关于第一部分的注释:EJB bean 也可以放在 war 中。war/ear 的区别并不在于 EJB。同时请注意,Servlet 容器和 Java EE AS(Web Profile 或完整版)之间的区别不仅仅在于 EJB。Java EE 中还有许多其他 API! - Mike Braun
显示剩余8条评论

3
Sun Java Web Server、IBM WebSphere Application Server、WebLogic、JBoss Application Server、Tomcat、Jetty... 它们都是 Java Web 应用服务器,并且执行相同的任务 - 运行您的 WAR 或 EAR 打包应用程序(EAR 是 "企业级",包含 1 个或多个 WAR)。
如果您在设置中有两个服务器来运行一个应用程序,则很可能在部署策略/设计方面出了问题。
有一些多服务器设置的情况,但这些通常是负载平衡和代理设置,其中 Apache HTTP Server 在您的 Java 应用服务器前面。
例如,您有一个 Tomcat 在端口 8080 上提供应用程序服务,并且希望使用 http://myserver.com/myapp/ 而不是 http://myserver.com:8080/myapp/。您不能仅使用 Tomcat 实现此目的,因为 Java 无法低于端口 1024 (*)。为了实现这一点,您需要在端口 80 上设置 Apache HTTP Server,并配置其 mod_proxy 将所有流量从 /myapp 重定向到 http://myserver.com:8080/myapp
*: 我记不清确切的数字,但大约是 1024。这适用于 Linux,但可能不适用于 Windows,因为我已经有一段时间没有使用 Windows 设置了。 更新: 我的错误,我忘记强调 "作为系统服务运行" 这一部分,如这里所述

1

既然应用服务器已经在内部包含了Servlet容器,那么再有一个处理传入http请求的Web服务器是多余的。

然而,在我参与的某个项目中,这些层被分离了。我们有一组JBoss服务器和一个单独的Tomcat服务器集群。Tomcat通过RMI调用JBoss并进行负载平衡。这样做是为了安全性(JBoss服务器在VPN内)和可扩展性。


我正在工作的项目中,他们正在使用SUN Java Web Server和Weblogic插件来转发请求。 - ilovetolearn
Tomcat通过RMI调用JBoss?这对安全有什么帮助呢?那你又如何使用JSF、JAX-RS、Bean Validation等呢?这些在Web层非常有用,而Tomcat并不具备这些功能。 - Mike Braun
并非每个人都需要JSF、JAX-RS等,安全优势在这种情况下相当有争议。但是存在一些顾虑。数据库和Jboss位于同一台机器上。敏感业务数据(配置、数据库等)位于VPN内的该机器上。如果恶意攻击者以某种方式获取了公共Tomcat的访问权限,他将无法访问数据库。另外还有其他RMI客户端需要调用与Tomcat一起使用的JBoss,核心业务逻辑位于JBoss中。 - Anton

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