问题 Tomcat - 按特定顺序启动webapps


我知道Tomcat和Servlet规范 不支持按特定顺序启动Web应用程序

然而,在我看来,这似乎是一个常见的用例,我想知道是否有人发现了一个聪明的解决方法。

我有webapp A,它使用Spring Remoting来公开共享服务,其中webapp B是一个客户端。除非webapp A正在运行,否则Webapp B无法初始化。但是,我的Tomcat始终是线性启动webapps,从webapp B开始。

出于基础结构的原因,我必须在同一个Tomcat服务器上运行它们。

有任何想法吗?

谢谢, 罗伊

UPDATE  -

事实证明,在我的特定情况下,订单无关紧要。原因是这样的:假设我使用下面的方法之一在应用程序B之前启动应用程序A.所以应用程序A启动,但是,由于Spring远程处理正在使用HTTP Invoker,HTTP端口尚未打开(它将无法打开直到 所有 应用程序已启动)。所以A将开始,B将挂起,因为它正在寻找的端口尚不可用。卫生署。

最终结果是两个单独的Tomcat实例。


10925
2018-01-09 19:19


起源

让需要等待其他Web应用程序的Web应用程序等待而不是失败并放弃。 - Dave Newton
嘿戴夫,不。他们不是并行开始的.B开始(好吧,试图开始)然后A将开始。但是如果B因为无法连接到A而无法启动,则A永远不会尝试启动。 - Roy Truelove
它应该以ASCII顺序启动它们。我在Debian Apache安装上看到的一个技巧是创建一个000_default,001_default命名约定。这使得在查看目录列表的ASCII顺序时更加清晰。 - speeves


答案:


我们遇到了同样的问题,为了解决这个问题,我们依赖的事实(我知道很滑)应用程序是按照它们定义的顺序启动的。 <tomcat_home>/conf/server.xml

这当然有一个缺点是硬编码应用程序 server.xml 但我们可以忍受它。


4
2018-01-10 12:44



谢谢mindas - 这可能是“最好”的方式,但不适合我 - 我会编辑我的问题来解释原因。 - Roy Truelove


如果您不关心破解一些tomcat代码并创建自己的Host实例,那么这很容易实现

1)创建一个org.apache.catalina.core.StandardHost的子类,比如说MyHost:

    class MyHost extends org.apache.catalina.core.StandardHost{
        public MyHost (){
        super();
        //changing HashMap for a predictable ordered Map :)
        this.children = new LinkedHashMap();
        }
    } 

2)在服务器的xml主机标签上注册你的课程()

尽管看起来令人难以置信,只要您在Host标签内以正确的顺序声明所有Web应用程序,它就能解决问题:

    <Host>
     <context app1>
     <context app2>
   </Host>

Thaen app1将在app2之前启动,无论你使用哪个。


4
2018-06-07 04:05



第一步之后,我们应该把MyHost类放在哪里?你能详细说明吗? - abi1964
我们可以有主机配置的例子吗? - Maayan Hope


理论上你可以产生一个 Runnable 通过 ExecutorService 在 contextInitialized() 它反过来以定时间隔检查其他webapp的可用性(可能通过触发HTTP HEAD 请求?)。一旦其他webapp可用,然后在servlet上下文中设置一些指示该属性的属性。添加一个 Filter 检查是否存在该属性并相应地阻止/继续请求。


1
2018-01-10 13:41





我知道这个问题有点陈旧,但我在尝试做同样的事情时发现它并认为我会用更好的解决方案更新...

您可以在server.xml中定义多个服务,这些服务在不同的端口上运行。服务按照它们在server.xml中出现的顺序依次启动。这意味着您可以 - 例如 - 在第一个服务中运行配置服务,然后在第二个服务中运行依赖它的应用程序(我使用默认的Catalina一个用于其余服务......)

你可以在这里看到更多信息: http://wiki.apache.org/tomcat/FAQ/Miscellaneous#Q27

这是我提供的服务 之前 Catalina服务:

<Service name="ConfigService">
    <Connector port="8081" protocol="HTTP/1.1"
        connectionTimeout="20000"
        redirectPort="8444" />
    <Engine name="ConfigServiceEngine" defaultHost="localhost">
        <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">

            <Context path="/" reloadable="true" docBase="/path/to/your/service/directory" />
        </Host>
    </Engine>
</Service>

正如您所看到的,我使用docbase而不是appBase,但如果您愿意,您应该能够配置不同的appBase ...

注意,更改服务和引擎的名称非常重要。

HTH


1
2018-03-26 12:26





这是Linux上的另一个技巧。

由于错误的WSDL,我们的一些Web服务应用程序无法部署。如果在许多其他应用程序之后部署或启动它们,则会发生这种情况。 它们的启动顺序取决于在/ opt / apache-tomee / conf / Catalina / localhost中找到上下文xml的顺序

可以使用“验证”ls -1f“。普通的”ls“给出一个排序的输出。

这曾经是文件添加到该目录的顺序,但是对于ext4文件系统,顺序基于文件名的哈希。这可以禁用如下:

# tune2fs -O ^dir_index /dev/xyz

现在你至少可以决定自己将以何种顺序开始。重新排序:将所有文件移动到临时文件夹,按所需顺序将其移回。


1
2018-05-18 09:47





这是一个很好的技巧,我用来创建2级webapp加载。在每个级别,订单不保证。这取决于tomcat将从tomcat / conf / [Engine Name] / [Host Name]加载第一个上下文描述符,然后才从server.xml中Host元素的appBase属性加载上下文。

只需在想要在第二级加载的webapp中的某处添加以下代码(即稍后)

File contextDescriptor = new File(getParameter("catalina.home"),"/conf/Catalina/localhost/mywebapp.xml");
contextDescriptor.deleteOnExit();

0
2018-03-20 13:03