java 我怎样才能找出我的 WAR 部署在 Tomcat 上需要这么长时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10857575/
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
How can I find out what's taking my WAR so long to deploy on Tomcat?
提问by James Adams
I have a web application which often takes an inordinate amount of time to deploy on Tomcat. My suspicion is that there's a database connection somewhere that's waiting until a timeout, but that's just a guess and I want to find out for sure what's causing the hold up so I can remedy the issue. Can anyone suggest a way I can go about doing this? Should I profile Tomcat when it's loading the WAR and look there for clues? If so is there a tutorial somewhere that's good for a beginner?
我有一个 Web 应用程序,它在 Tomcat 上部署通常需要过多的时间。我怀疑某处有一个数据库连接在等待超时,但这只是一个猜测,我想确定是什么导致了阻塞,以便我可以解决这个问题。任何人都可以建议我可以这样做吗?我应该在加载 WAR 时分析 Tomcat 并在那里寻找线索吗?如果是这样,是否有适合初学者的教程?
In case this matters my web application uses Spring and Hibernate. I've been told by a colleague that perhaps these are causing the slow down in that they are so huge that somewhere a class loader is choking on the sheer number of classes it needs to load.
如果这很重要,我的 Web 应用程序使用 Spring 和 Hibernate。一位同事告诉我,也许这些是导致速度变慢的原因,因为它们太大了,以至于某个类加载器因需要加载的绝对数量的类而窒息。
Also I see this when I stop Tomcat or hot deploy the WAR to an already running Tomcat:
当我停止 Tomcat 或将 WAR 热部署到已经运行的 Tomcat 时,我也会看到这一点:
Jun 1, 2012 6:03:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/nacem-rest] registered the JDBC driver [oracle.jdbc.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Jun 1, 2012 6:03:34 PM org.apache.catalina.startup.HostConfig deployWAR
Perhaps this is part of the problem? Redeploying my web application almost always requires a restart of Tomcat as well, and I've always assumed that the above mentioned JDBC driver issue was to blame, but maybe it also has something to do with the sluggish start time as well?
也许这是问题的一部分?重新部署我的 Web 应用程序几乎总是需要重新启动 Tomcat,而且我一直认为是上面提到的 JDBC 驱动程序问题是罪魁祸首,但也许它也与缓慢的启动时间有关?
回答by Tomasz Nurkiewicz
You can use a profiler, but it is a bit of an overkill. Instead just make few thread dumps while the application loads. You can use jstack
or jvisualvm
, plenty of resources over the net describing how to do this. Basically you need a PID of your Tomcat (see: jps
).
您可以使用分析器,但这有点矫枉过正。而是在应用程序加载时进行少量线程转储。您可以使用jstack
或jvisualvm
,网络上的大量资源描述如何执行此操作。基本上,您需要 Tomcat 的 PID(请参阅:)jps
。
If you find it hard to analyse the thread dump - add it to your question. Typically it's pretty easy to find a bottleneck. Typical problems:
如果您发现很难分析线程转储 - 将其添加到您的问题中。通常很容易找到瓶颈。典型问题:
- the application tries to fetch some resource from the Internet like XML schema
- a lot of classes to scan on the CLASSPATH
- excessive GC (enable verbose gc logging just in case)
- not enough memory (swapping, see
iostat
/iotop
)
- 应用程序尝试从 Internet 获取一些资源,例如 XML 模式
- 很多类要在 CLASSPATH 上扫描
- 过多的 GC(为了以防万一,启用详细的 gc 日志记录)
- 内存不足(交换,见
iostat
/iotop
)
回答by Simone Gianni
the first I would look is how the CPU or RAM usage of tomcat perform during your application startup.
我首先要看的是在您的应用程序启动期间 tomcat 的 CPU 或 RAM 使用情况。
If you see a lot of CPU activity and RAM increase, then it's probably loading a lot of stuff, like a lot of classes, or performing some kind of huge pre-allocation or similar. In that case thread dumps can help you a lot, but also "lsof" (if your tomcat is running on an *nix environment) to see what files it is currently working on.
如果你看到大量 CPU 活动和 RAM 增加,那么它可能正在加载很多东西,比如很多类,或者执行某种巨大的预分配或类似的。在这种情况下,线程转储可以帮助您很多,但也可以通过“lsof”(如果您的 tomcat 在 *nix 环境中运行)来查看它当前正在处理哪些文件。
However, if you see it simply sitting there, then it is probably waiting on some kind of connection.
但是,如果您看到它只是坐在那里,那么它可能正在等待某种连接。
One cause may be a DB connection, as you supposed. The DB is usually fast to answer, and a failed attempt to connect to a DB is usually clearly logged somewhere, but still it could be.
如您所料,一个原因可能是数据库连接。DB 通常可以快速响应,并且连接到 DB 的失败尝试通常会清楚地记录在某处,但它仍然可能是。
Another, less known, cause may be some XML validation. It is not uncommon for a web application to load some XML data, and it is not uncommon to use a validating parser to load that XML. The validating parser needs a schema or DTD to validate, and the URL for the schema/DTD file is often included in the XML. So, some parsers will try to load the schema file from internet to validate the XML, and that could take a lot of time being an internet connection. Moreover, some parsers will fail silently and simply not validate the XML, probably after a rather long timeout. Sorry for being vague on "some parsers" etc.. but if XML loading is done by libraries used inside your webapp, they could use the JVM XML parser, any possible version of Xerces, any possible version for JDOM etc... and even worst different libraries may be using different parsers.
另一个鲜为人知的原因可能是一些 XML 验证。Web 应用程序加载一些 XML 数据的情况并不少见,使用验证解析器加载该 XML 的情况并不少见。验证解析器需要模式或 DTD 来验证,模式/DTD 文件的 URL 通常包含在 XML 中。因此,一些解析器会尝试从 Internet 加载模式文件以验证 XML,这可能需要很长时间才能连接到 Internet。此外,一些解析器会默默地失败并且根本不验证 XML,可能是在相当长的超时之后。很抱歉在“某些解析器”等方面含糊不清……但是如果 XML 加载是由您的 web 应用程序内部使用的库完成的,他们可以使用 JVM XML 解析器、任何可能的 Xerces 版本、任何可能的 JDOM 版本等......
However, if it is a connection problem, it's easier to see it using "netstat -anlp | grep java" (in your tomcat is on a *nix environment, otherwise it should be "netstat -ano" on windows), and looking for what outgoing connection your tomcat is trying to make. There you can see DB connections and also outgoing (usually http) connections searching for schemes or other stuff.
但是,如果是连接问题,使用“netstat -anlp | grep java”(在您的 tomcat 中是在 *nix 环境中,否则在 Windows 上应该是“netstat -ano”)更容易看到它,并寻找你的 tomcat 试图建立什么传出连接。在那里您可以看到数据库连接以及搜索方案或其他内容的传出(通常是 http)连接。
回答by Pidster
If you are using Tomcat 7.0.x, it might be scanning the classpath to detect annotations. If you have a lot of jars / classes, then this can be an issue.
如果您使用的是 Tomcat 7.0.x,它可能会扫描类路径以检测注释。如果你有很多罐子/类,那么这可能是一个问题。
As Simone says, taking and analysing a couple of thread dumps is a good way to start.
正如 Simone 所说,获取和分析几个线程转储是一个很好的开始方式。
If you are not using a recent version of Tomcat, try upgrading & checking the conf/catalina.properties file for hints on how to reduce the number of jars that are scanned.
如果您使用的不是最新版本的 Tomcat,请尝试升级和检查 conf/catalina.properties 文件以获取有关如何减少扫描的 jar 数量的提示。
回答by npe
You should take a few thread dumps during deployment (the more the better), and analyze them. Look for blocks, waits etc. Thread Dump Analyzermight be of use.
您应该在部署期间进行一些线程转储(越多越好),并对其进行分析。寻找块、等待等。线程转储分析器可能有用。
回答by Tu?n Lé
This may be relate to this BUG of JDK
I readed this article, Tomcat7 starts too late on Ubuntu 14.04 x64and resolved my problem.
我读了这篇文章,Tomcat7 在 Ubuntu 14.04 x64 上启动太晚并解决了我的问题。
Try to resolve it by Replacingsecurerandom.source=file:/dev/urandom with securerandom.source=file:/dev/./urandom in $JAVA_PATH/jre/lib/security/java.security
尝试通过在 $JAVA_PATH/jre/lib/security/java.security 中用 securerandom.source=file:/dev/./urandom替换securerandom.source=file:/dev/urandom来解决它
回答by user3590949
I found that I had a large delay when deploying a web application to Tomcat8. I had three database connection pools configured in my context.xml file within the WAR. Each connection pool had an initial count of 10 connections so Tomcat was creating 30 database connections at startup. I found that configuring each pool for 1 initial connection on my test system improved the deploy time from approximately 3 minutes to 22 seconds.
我发现我在部署一个web应用到Tomcat8的时候有很大的延迟。我在 WAR 中的 context.xml 文件中配置了三个数据库连接池。每个连接池的初始计数为 10 个连接,因此 Tomcat 在启动时创建了 30 个数据库连接。我发现在我的测试系统上为每个池配置 1 个初始连接将部署时间从大约 3 分钟缩短到 22 秒。
回答by Sangameshrh
Append below in setenv.sh
of your working tomcat7/bin
directory:
在setenv.sh
您的工作tomcat7/bin
目录中添加以下内容:
JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"
JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"