将多个应用程序部署到 Tomcat

Posted

技术标签:

【中文标题】将多个应用程序部署到 Tomcat【英文标题】:deploying multiple applications to Tomcat 【发布时间】:2014-06-27 11:19:36 【问题描述】:

我想将两个应用程序 foo.warbar.war 部署到同一个 Tomcat 实例。他们是否可以侦听不同端口上的连接,例如foo 监听 81 端口,bar 监听 82 端口?如果是这样,我该如何配置?我意识到应用程序没有必要监听不同的端口,但这就是我想要实现的。

另外,如果我将 foo.war 重命名为 ROOT.war 以使其在根上下文中运行,那么我是否正确,那么对此 Tomcat 实例的所有请求都将由 foo 应用程序处理,因此 bar 必须部署到单独的 Tomcat 实例?

【问题讨论】:

相关:***.com/questions/8823290/… 我可能错过了为什么我们可能需要监听不同的端口? 【参考方案1】:

如果你想让Tomcat监听多个端口,你需要为每个端口设置一个连接器。要将每个端口映射到不同的应用程序,您需要将每个连接器包装在 service 中并使用它自己的appBase 创建一个 host

server.xml中的服务定义示例:

<Service name="foo">
    <Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol" />
    <Engine name="Catalina80" defaultHost="localhost">
        <Host name="localhost" appBase="foo" unpackWARs="true" autoDeploy="true" />
    </Engine>
</Service>

<Service name="bar">
    <Connector port="81" protocol="org.apache.coyote.http11.Http11NioProtocol" />
    <Engine name="Catalina81" defaultHost="localhost">
        <Host name="localhost" appBase="bar" unpackWARs="true" autoDeploy="true" />
    </Engine>
</Service>

您需要为端口80 创建目录foo 并为端口81 创建bar,而不是将war 文件放到webapps 目录中。将两个战争文件命名为ROOT.war 并将它们放在它们自己的基本目录中。如果需要,您当然可以在每个目录中拥有多个应用程序。

appBase 中定义的目录是相对于 tomcat 目录的。通过使用绝对路径,它可以位于系统上的任何位置。来自documentation:

appBase

此虚拟主机的 Application Base 目录。这是一个目录的路径名,其中可能包含要部署在此虚拟主机上的 Web 应用程序。您可以指定绝对路径名,或相对于$CATALINA_BASE 目录的路径名。 [...] 如果未指定,将使用默认值 webapps

另一种选择是保留默认的 tomcat 配置并使用另一个 http 服务器(apache、nginx、lighttpd...)将端口映射到 tomcat 应用程序的内部路径。

根应用程序不会接收与其他应用程序匹配的请求,例如/foo/example 将转到 foo.war/example/example 将转到 ROOT.war

【讨论】:

感谢您的回复,您提到的foobar 目录是否应该在webapps 下创建? 我会在别处创建它们,否则如果 webapps 仍被其他连接器用作 appBase,应用程序可能会部署两次。 根据上面的配置,foobar目录应该放在哪里? 路径应该相对于 tomcat 目录 ($CATALINA_HOME),具体取决于您的系统。你也可以使用绝对路径,比如/usr/home/foo 正确。我用文档中的一些信息更新了答案。【参考方案2】:

无需更改端口

Java Servlet 技术的目的是在使用多个正在运行的 Web 应用程序中的多个用户之间处理多个传入请求和传出响应。所有这些流量都可以在一个端口上处理。

只需将两个 war 文件放入 Tomcat 的 webapps 文件夹即可。这就是你需要做的。

默认情况下,Tomcat 将每个战争(技术上是一个 zip 文件)展开(有人说是“爆炸”)到一个文件夹中,并自动为您部署应用程序。如果 Tomcat 已经在运行,或者在您启动 Tomcat 时启动,则会发生这种情况。有些人关闭了生产环境的自动部署功能,以节省 Tomcat 扫描新战争文件的工作。

不需要多个端口。 Servlet 容器的工作是检查 URL 并确定应该调用哪个 Servlet。

默认情况下,war 文件的名称决定 URL。鉴于你的例子:

http://www.example.com/foo --> foo.war

http://www.example.com/bar --> bar.war

http://www.example.com/ --> ROOT.war

所有网络应用程序都可以在同一个端口上提供服务。您对端口的唯一关注是您是否使用保护对低编号端口的访问的 Unix 风格的操作系统。这包括 Mac OS X、BSD、Linux 和 Solaris。在您的 URL 中使用高编号端口(Tomcat 默认为 8080),或使用port-forwarding 将端口 80(Web 浏览器默认)上的传入请求发送到 Tomcat 的端口(例如 8080)。

如果您希望使用不同的域来提供战争文件,请了解 Tomcat 中的“虚拟主机”设置。

【讨论】:

感谢您花时间在这方面,但它不能回答我的任何一个问题 (1) 是否可以将不同的应用程序部署到同一个 Tomcat 实例上并监听不同的端口? (2) 如果一个应用被部署到 Tomcat 的根上下文,它会处理所有发送到该 Tomcat 实例的 HTTP 请求吗? @Dónal RE:(1) 我不知道单独的端口。在server.xml 文件中查看Service 标记的Connector 标记。但是不需要单独的端口。 URL 是所有 Web 服务器/servlet 容器为不同 Web 应用程序分离请求所需的。 (2) 最具体的 URL(更长,意味着更多的组件)由它们定义的 servlet 处理。我的答案中上面发布的三个项目的项目符号列表都可以一起部署。如果 URL 指定“foo”,您将获得“foo”servlet。如果 URL 未指定,则返回到 ROOT servlet。 我意识到没有必要让每个应用都监听一个单独的端口,但这就是我想要实现的目标 虽然它没有解决问题的具体要点,但它是一个很好的解释,并阐明了一般 servlet 容器工作的一些基本概念。感谢@Dónal 的努力和时间 @SurajGautam 当然,您可以部署与 Web 应用程序一样多的 WAR 文件。每个都有自己的 URL 供用户调用。【参考方案3】:

我已成功配置 Tomcat 以在多个端口上运行应用程序。我不知道这是否是最好的方法,但我只是复制了

的内容
<Service>...</Service>

在 conf/server.xml 中并更改了 Connector 标签的端口并更改了 Host 标签的 appBase 属性。您可以根据部署到的 appBase 来控制您的应用在哪个端口上运行。

【讨论】:

【参考方案4】:

我已经在做 Basil 上面提到的事情了。

事实证明,我需要对我的 sites-enabled/blah.conf 文件进行通配符,以不引用我在添加另一个应用程序前几个月部署的第一个(也是唯一一个).war。

这是我使用通配符的:

文档根目录 JkMount 目录 目录索引

所以仅供参考,你们会的。 :)

【讨论】:

什么是 sites-enabled/blah.conf 你能详细说明一下 DocumentRoot、JkMount 等在哪里...

以上是关于将多个应用程序部署到 Tomcat的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot应用部署到外部Tomcat

AWS Elastic Beanstalk 上的 Tomcat:公开多个端口

使用 Apache/Tomcat + 虚拟主机部署多个 grails 应用程序

一个tomcat部署多个应用实例总结

tomcat服务器中的web应用程序部署在哪个物理位置

如何在一个 Tomcat + Apache 上部署多个 Grails 应用程序?