Optimizing tomcat startup time

人盡茶涼 提交于 2019-12-05 04:39:10

You are probably assuming that Tomcat is, by default, doing something inefficient when deploying your webapp, and that if you make just the right change you can kludge around it and make your webapp start much faster. Those are not safe assumptions to make. Tomcat tends to be very efficient, even handling large webapps.

It sounds to me like your webapp is large enough where the JDK is not able to load that huge number of classes and instantiate that large number of objects in less time than 13 seconds. The time is likely spent mainly in instantiating & initializing servlets and everything that they require, which is a very large amount of work to do if your webapp has many large subsystems to initialize before serving requests. Doing all of that can certainly take tens of seconds, and during that time not much of it is spent parsing config files, even opening JARs to find and parse some.

Why your webapp fails to start with a static metadata-complete deployment descriptor, I don't know, in part because you're not saying it what specific way it's failing when it fails. But, it's likely that by setting metadata-complete to true you have bypassed a necessary part of webapp startup that your webapp depends on.

A Potential Startup Optimization

Something that you might configure specifically for your large webapp that could save Tomcat a significant amount of time looking through your webapp's files is: skipping JARs that you know Tomcat shouldn't scan for certain things such as Servlet 3 fragments and TLDs. Have a look at your Tomcat's conf/catalina.properties file.. these configurable system properties are in there:

# Additional JARs (over and above the default JARs listed above) to skip when
# scanning for Servlet 3.0 pluggability features. These features include web
# fragments, annotations, SCIs and classes that match @HandlesTypes. The list
# must be a comma separated list of JAR file names.
org.apache.catalina.startup.ContextConfig.jarsToSkip=

# Additional JARs (over and above the default JARs listed above) to skip when
# scanning for TLDs. The list must be a comma separated list of JAR file names.
org.apache.catalina.startup.TldConfig.jarsToSkip=tomcat7-websocket.jar

Add all of your JARs that should be skipped when Tomcat is searching for these, and my guess is that Tomcat's part of starting your webapp will complete sooner. How much sooner depends on the webapp.

Answering my own questions:

2) Can you explain why setting metadata-complete to true does not help to reduce the 13s ?

Metadata-complete attribute does not control directly class annotation scanning. It controls if web-fragments will be discovered, and then in-turn the classes contained in these fragments will be scanned.

Provided the same web fragments are enabled in <absolute-ordering> (or left empty), ServletContainerInitializer.onStartup(Set>, ServletContext) will receive the same set of annotated classes independently of the value of metadata-complete.

So, by itself changing the value of metadata-complete will not have an impact on exploded war deployment / class scanning. Changes will happen only if the webfragments are specified.

As a side effect, jars not part of a web fragement will not be scanned which may cause problem with annotated classes in TLDs. It is thus important that all components of the applications are web fragments to benefit from this optimization.

3) Altough my web.xml is complete, why it does not allow the app to start ?

With option logEffectiveWebXml="true" set on conf/context.xml, are only logged listeners and filters. ServletContainerInitializers (SCIs) are not specified.

If <absolute-ordering> is not set in web.xml, SCIs will be discovered as part of the web fragment scanning. If it is set empty as in my example above, all web fragments will be skipped and hence the application will not start.

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