java 优化tomcat启动时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25867282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 08:49:33  来源:igfitidea点击:

Optimizing tomcat startup time

javatomcatstartup

提问by loic tregan

My application is pretty large, containing for instance 310 jars in web-inf/lib for a total of 100Mb. Starting the server, this step below takes 13s:

我的应用程序非常大,例如在 web-inf/lib 中包含 310 个 jar,总共 100Mb。启动服务器,下面这一步需要13s:

Sep 16, 2014 1:05:33 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory C:\apache-tomcat-7.0.47\webapps\ROOT

The application relies on web-fragment and annotations to start properly.

该应用程序依赖于 web-fragment 和注释才能正常启动。

I tried the following to skip the 13s scanning time:

我尝试了以下方法来跳过 13 秒的扫描时间:

  • modify conf/context.xml with attribute logEffectiveWebXml="true"

  • catalina run 2> web-complete.log

  • extract the web.xmlsnippet from web-complete.log, save it under webapps\ROOT\web-inf\web.xml

  • 调整 conf/context.xml with attribute logEffectiveWebXml="true"

  • catalina run 2> web-complete.log

  • web.xml从 中提取片段web-complete.log,将其保存在webapps\ROOT\web-inf\web.xml

If I start my application, I still see 13s scanning time. metadata-complete was already set to "true" in the snipet above.

如果我启动我的应用程序,我仍然看到 13 秒的扫描时间。metadata-complete 在上面的 snipet 中已经设置为“true”。

After adding the following statement to web.xml skips the 13s altogether, but this time my application cannot start anymore:

将以下语句添加到 web.xml 后,完全跳过了 13 秒,但这次我的应用程序无法再启动:

<absolute-ordering />

1) What would be the proper way to make tomcat start fast in my case ?

1)在我的情况下,让tomcat快速启动的正确方法是什么?

2) Can you explain why metadata-complete does not help on the 13s ?

2)你能解释一下为什么元数据完整对 13s 没有帮助吗?

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

3) 虽然我的 web.xml 是完整的,为什么不允许应用程序启动?

Thanks,

谢谢,

回答by Yavin5

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.

您可能认为 Tomcat 在默认情况下在部署您的 web 应用程序时会做一些低效的事情,并且如果您做出正确的更改,您可以围绕它进行调整,并使您的 web 应用程序启动得更快。这些都不是安全的假设。Tomcat 往往非常高效,即使处理大型 web 应用程序也是如此。

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.

在我看来,您的 web 应用程序足够大,JDK 无法在不到 13 秒的时间内加载大量的类并实例化大量的对象。时间可能主要用于实例化和初始化 servlet 以及它们所需的一切,如果您的 web 应用程序有许多大型子系统要在处理请求之前进行初始化,那么这将是一项非常大量的工作。完成所有这些工作肯定会花费数十秒,在此期间,解析配置文件的时间并不多,甚至打开 JAR 以查找和解析一些配置文件。

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.

为什么您的 web 应用程序无法以静态元数据完整部署描述符启动,我不知道,部分原因是您没有说明它失败时失败的具体方式。但是,很可能通过将 metadata-complete 设置为 true,您已经绕过了您的 webapp 所依赖的 webapp 启动的必要部分。

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:

您可以专门为大型 web 应用程序配置的一些内容可以为 Tomcat 节省大量时间查看您的 web 应用程序文件:跳过您知道 Tomcat 不应该扫描某些内容的 JAR,例如 Servlet 3 片段和 TLD。看看你的 Tomcat 的 conf/catalina.properties 文件。这些可配置的系统属性在那里:

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

添加所有在 Tomcat 搜索这些 JAR 时应该跳过的 JAR,我猜测 Tomcat 启动 web 应用程序的部分将更快完成。多快取决于网络应用程序。

回答by loic tregan

Answering my own questions:

回答我自己的问题:

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

2)你能解释为什么将 metadata-complete 设置为 true 无助于减少 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.

Metadata-complete 属性不直接控制类注释扫描。它控制是否会发现网络片段,然后依次扫描这些片段中包含的类。

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.

如果在 <absolute-ordering> 中启用了相同的 web 片段(或留空), ServletContainerInitializer.onStartup(Set>, ServletContext) 将独立于 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.

因此,改变 metadata-complete 的值本身不会对爆炸War部署/类扫描产生影响。仅当指定了 webfragments 时才会发生更改。

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.

作为副作用,不属于 Web 片段的 jar 将不会被扫描,这可能会导致 TLD 中的注释类出现问题。因此,重要的是应用程序的所有组件都是网络片段,以便从这种优化中受益。

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

3) 虽然我的 web.xml 是完整的,为什么它不允许应用程序启动?

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

在 conf/context.xml 上设置选项 logEffectiveWebXml="true" 时,只有记录的侦听器和过滤器。未指定 ServletContainerInitializers (SCI)。

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.

如果 web.xml 中未设置 <absolute-ordering>,则 SCI 将作为 Web 片段扫描的一部分被发现。如果它像我上面的例子一样设置为空,所有的 web 片段都将被跳过,因此应用程序将不会启动。