8

我有一个 Web 应用程序,通常需要花费大量时间才能在 Tomcat 上部署。我怀疑某处有一个数据库连接正在等待超时,但这只是一个猜测,我想确定是什么导致了阻塞,以便我可以解决这个问题。谁能建议我可以这样做的方法?我应该在加载 WAR 时分析 Tomcat 并在那里寻找线索吗?如果是这样,是否有适合初学者的教程?

如果这很重要,我的 Web 应用程序使用 Spring 和 Hibernate。一位同事告诉我,也许这些会导致速度变慢,因为它们太大了,以至于某个类加载器在需要加载的类的绝对数量上窒息。

当我停止 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

也许这是问题的一部分?重新部署我的 Web 应用程序几乎总是需要重新启动 Tomcat,而且我一直认为上面提到的 JDBC 驱动程序问题是罪魁祸首,但也许它也与缓慢的启动时间有关?

4

7 回答 7

8

您可以使用探查器,但这有点过头了。相反,只需在应用程序加载时进行少量线程转储。您可以使用jstackor jvisualvm,网络上描述如何执行此操作的大量资源。基本上,您需要 Tomcat 的 PID(请参阅:jps)。

如果您发现很难分析线程转储 - 将其添加到您的问题中。通常很容易找到瓶颈。典型问题:

  • 应用程序尝试从 Internet 获取一些资源,例如 XML 模式
  • 很多类要在 CLASSPATH 上扫描
  • 过多的 GC(启用详细的 gc 日志记录以防万一)
  • 没有足够的内存(交换,见iostat/ iotop
于 2012-06-01T21:31:46.907 回答
5

我首先要看的是在您的应用程序启动期间,tomcat 的 CPU 或 RAM 使用情况如何。

如果你看到大量的 CPU 活动和 RAM 增加,那么它可能加载了很多东西,比如很多类,或者执行某种巨大的预分配或类似的。在这种情况下,线程转储可以帮助您很多,但也可以通过“lsof”(如果您的 tomcat 在 *nix 环境中运行)查看它当前正在处理的文件。

但是,如果您看到它只是坐在那里,那么它可能正在等待某种连接。

如您所料,一个原因可能是数据库连接。数据库通常可以快速回答,连接数据库失败的尝试通常会清楚地记录在某处,但它仍然可能是。

另一个鲜为人知的原因可能是一些 XML 验证。Web 应用程序加载一些 XML 数据的情况并不少见,使用验证解析器加载该 XML 数据的情况并不少见。验证解析器需要一个模式或 DTD 来验证,并且模式/DTD 文件的 URL 通常包含在 XML 中。因此,一些解析器会尝试从 Internet 加载模式文件以验证 XML,而这可能需要大量时间作为 Internet 连接。此外,一些解析器会默默地失败并且根本不验证 XML,可能是在相当长的超时之后。抱歉对“某些解析器”等含糊不清。但如果 XML 加载是由您的 webapp 中使用的库完成的,他们可以使用 JVM XML 解析器、任何可能的 Xerces 版本、任何可能的 JDOM 版本等......

但是,如果是连接问题,使用“netstat -anlp | grep java”会更容易查看(在您的 tomcat 中是在 *nix 环境中,否则在 Windows 上应该是“netstat -ano”),并寻找你的tomcat试图建立什么样的传出连接。在那里您可以看到数据库连接以及搜索方案或其他内容的传出(通常是 http)连接。

于 2012-06-01T22:32:55.340 回答
4

如果您使用的是 Tomcat 7.0.x,它可能会扫描类路径以检测注释。如果您有很多罐子/类,那么这可能是一个问题。

正如 Simone 所说,获取和分析几个线程转储是一个很好的开始方式。

如果您使用的不是最新版本的 Tomcat,请尝试升级并检查 conf/catalina.properties 文件以获取有关如何减少扫描的 jar 数量的提示。

于 2012-06-03T14:45:20.543 回答
3

您应该在部署期间进行一些线程转储(越多越好),并对其进行分析。查找块、等待等。线程转储分析器可能有用。

于 2012-06-01T21:31:54.880 回答
1

这可能与JDK的这个BUG有关

读了这篇文章,Tomcat7 在 Ubuntu 14.04 x64 上启动太晚了,解决了我的问题。

尝试通过在 $JAVA_PATH/jre/lib/security/java.security 中将 securerandom.source=file:/dev/urandom 替换为 securerandom.source=file:/dev/./urandom 来解决

于 2015-07-13T05:49:58.190 回答
0

我发现在将 Web 应用程序部署到 Tomcat8 时出现了很大的延迟。我在 WAR 中的 context.xml 文件中配置了三个数据库连接池。每个连接池的初始连接数为 10 个,因此 Tomcat 在启动时创建了 30 个数据库连接。我发现在我的测试系统上为每个池配置 1 个初始连接将部署时间从大约 3 分钟缩短到 22 秒。

于 2016-05-27T15:04:57.727 回答
-3

setenv.sh在您的工作tomcat7/bin目录中附加以下内容:

JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"

于 2016-11-14T18:01:25.360 回答