Is there a way to enforce a deployment order in tomcat6?

只愿长相守 提交于 2020-01-19 01:25:48

问题


I have 3 wars in my webapp folder. Two of them are built on services of the third one. I'm in a testing environment, i.e. I don't have control over their architectures, so I'm no able to change a thing. So...

Question: Is there a way to enforce a deployment order in tomcat?

I've ran into one question here in stackoverflow, but there's no solution.

Well, actually the guy suggests that changing the name of the webapps to an alphabetical order would help. However, I'm not willing to do that everytime I need to test those and different wars.

I'm positive that there's a way of doing that configuring one of the tomcat conf .xml files. I just don't know which one.


回答1:


From the Tomcat Wiki - What order do webapps start (or How can I change startup order)?

There is no expected startup order. Neither the Servlet spec nor Tomcat define one. You can't rely on the apps starting in any particular order.

Tomcat has never supported specifying load order of webapps. There are other containers like JBoss that do, but Tomcat never has. Any apparent behavior that looks like load ordering via the alphabetical order of the names of the web apps is coincidental and not guaranteed to work in all cases.

What you are probably thinking of is the <load-on-startup/> element if the web.xml that specifies order of loading servlets.

That said there is an elegant solution using a service discovery protocol.

One solution is to use something like ZeroConf and register your services when they start up, and then have the dependent apps look for when these services come available and have them connect and do what ever they need to do when the service is ready. This is how I have been handling multiple dependent services for years now. I have Python, Java and Erlang services all discovering each other via ZeroConf seemlessly.




回答2:


It is true that tomcat does not provide any way to enforce deployment order.

*Tomcat deploys webapps in following order:*

1.Any Context Descriptors will be deployed first.

2.Exploded web applications not referenced by any Context Descriptor will then be deployed. If they have an associated .WAR file in the appBase and it is newer than the exploded web application, the exploded directory will be removed and the webapp will be redeployed from the .WAR

3.WAR files will be deployed

> Here is a proposed solution:


If you want to specify the deployment order then define a context for your web app in $CATALINA_BASE/conf/[enginename]/[hostname]/MyApp.xml

Tomcat scans $CATALINA_BASE/conf/[enginename]/[hostname]/ by performing File listFiles() which returns a File array sorted by hash value (OS dependent).

You may use the following code to check in which order webapps will be deployed

File file = new File("/opt/tomcat/conf/Catalina/localhost");
        File[] files = file.listFiles();
        for (File f : files)
        {
            System.out.println("Filename: " + f.getName());
        }



回答3:


There are three ways to deploy the webapp.war in Tomcat.

  1. Add Context element inside a Host element in the $CATALINA_BASE/conf/server.xml file.

    <Server><Service><Engine><Host>
        <Context path="[webappName]" docBase="[webappPath]"/>
    </Server></Service></Engine></Host>
    
  2. Create the $CATALINA_BASE/conf/[engineName]/[hostName]/[webappName].xml file with content:

    <Context docBase="[webappPath]"/>
    
  3. Add the webapp.war file directly in the $CATALINA_BASE/webapps/ directory.

The following deployment sequence will occur on Tomcat startup:

1→2→3


Some explanations:

  • $CATALINA_BASE

    Refer the base directory against which most relative paths are resolved. If you have not configured Tomcat for multiple instances by setting a CATALINA_BASE directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, the directory into which you have installed Tomcat.

  • docBase

    The pathname to the web application WAR file. You may specify an absolute pathname for this WAR file, or a pathname that is relative to the appBase directory of the owning Host.

  • engineName:

    The name of the engine associated to the context. The default name is Catalina.

  • hostName:

    The name of the host associated to the context. The default name is localhost.


Assume that:

  • there are 3 webapps: a.war, b.war and c.war.
  • b.war depends on a.war.
  • c.war depends on b.war.
  • Server.Service.Engine.name = "Catalina"
  • Server.Service.Engine.Host.name = "localhost"
  • Server.Service.Engine.Host.appBase = "webapps"

Try the following steps:

  1. Put all of the war files to the $CATALINA_BASE/webapps/ directory.
  2. create the $CATALINA_BASE/conf/Catalina/localhost/b.xml file with content:

    <Context docBase="b.war"/>
    
  3. Add Context element in the $CATALINA_BASE/conf/server.xml file:

    <Server><Service><Engine><Host>
        <Context path="a" docBase="a.war"/>
    </Server></Service></Engine></Host>
    

Reference:

  • https://tomcat.apache.org/tomcat-9.0-doc/deployer-howto.html
  • http://tomcat.apache.org/tomcat-9.0-doc/config/context.html



回答4:


Apologies for cross posting (Tomcat - starting webapps in a specific order), but I thought it was relevant here too:

You can define mulitple services in your server.xml, which run on different ports. The services are started sequentially according to the order they appear in the server.xml. This means that you can have - for example - a configuration service running in the first service and then the apps that depend on it in the second (I use the default Catalina one for the rest of them...)

You can see more info here: http://wiki.apache.org/tomcat/FAQ/Miscellaneous#Q27

And this is the service that I include before the Catalina Service:

<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>

As you can see, I use docbase rather than appBase, but you should be able t configure a different appBase if you prefer...

NB it's important to change the name of both the service and the engine.

HTH




回答5:


You could always move the first .war file into the tomcat directory, then wait for it to deploy, then move the next two into the tomcat directory. This would deploy the first, then deploy the other two.

Alternatively you can possibly use the fact that Tomcat will scan the directory and deploy the first war, then second war, then third war alphabetically




回答6:


That's quite easy to achieve if you don't care hacking a bit of tomcat code and creating your own Host instance

1) Create a subClass of org.apache.catalina.core.StandardHost, say MyHost:

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

2) register your class on your server's xml Host tag ()

Incredible as it may seem, it solves the problem as long as you have all your web app declared in the correct order inside of Host tag:

<Host>
 <context app1>
 <context app2>

Thaen app1 will start before app2, no matter which SO you used.




回答7:


We run multiple tomcats. We can bring up groups of apps independently by putting the first group in one tomcat and the later ones in a second.

This assumes that they are not trying to communicate with each other using the JVM.



来源:https://stackoverflow.com/questions/6698646/is-there-a-way-to-enforce-a-deployment-order-in-tomcat6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!