将多个应用程序部署到 Tomcat
Posted
技术标签:
【中文标题】将多个应用程序部署到 Tomcat【英文标题】:deploying multiple applications to Tomcat 【发布时间】:2014-06-27 11:19:36 【问题描述】:我想将两个应用程序 foo.war
和 bar.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
。
【讨论】:
感谢您的回复,您提到的foo
和bar
目录是否应该在webapps
下创建?
我会在别处创建它们,否则如果 webapps
仍被其他连接器用作 appBase
,应用程序可能会部署两次。
根据上面的配置,foo
和bar
目录应该放在哪里?
路径应该相对于 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的主要内容,如果未能解决你的问题,请参考以下文章
AWS Elastic Beanstalk 上的 Tomcat:公开多个端口