How can I find out what makes my WAR deploy so long on Tomcat?

I have a web application that often takes too long to deploy to Tomcat. I suspect that somewhere there is a database connection that waits before the timeout expires, but this is just an assumption, and I want to find out what caused the delay so that I can fix the problem. Can someone suggest a way I can do this? Should I profile Tomcat when loading the WAR and look for clues there? If so, is there any good beginner guide somewhere?

In case that matters, my web application uses Spring and Hibernate. A colleague told me that perhaps they slow down in the fact that they are so large that somewhere the class loader suffocates from the huge number of classes that he needs to load.

I also see this when I stop Tomcat or do a hot deployment of WAR on an already running 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 restarting Tomcat, and I always assumed that the JDBC driver issue mentioned above was to blame, but maybe this also has something to do with slow startup time?

+8
source share
7 answers

You can use the profiler, but this is a bit overkill. Instead, just dump a few threads while the application loads. You can use jstack or jvisualvm , many resources on the network that describe how to do this. Basically you need your Tomcat PID (see jps ).

If it is difficult for you to analyze the stream dump, add it to your question. It is usually quite easy to find a bottleneck. Common problems:

  • an application is trying to retrieve some resource from the Internet, such as an XML schema
  • many classes to scan on CLASSPATH
  • excessive GC (enable verbose gc logging just in case)
  • not enough memory (replacement, see iostat / iotop )
+8
source

The first thing I would like to see is how the processor or RAM use tomcat during the launch of your application.

If you see a lot of processor activity and an increase in RAM, then it probably loads a lot of things, for example, many classes, or does some huge pre-allocation or the like. In this case, dump streams can help you a lot, but also "lsof" (if your tomcat works in * nix environment) to see which files it works in.

However, if you see that he is just sitting there, then he is probably waiting for some kind of connection.

One of the reasons could be the connection to the database, as you expected. The database usually responds quickly, and an unsuccessful attempt to connect to the database is usually distinctly recorded somewhere, but it can still be.

Another, less well-known reason may be some XML validation. Some XML data is often loaded for a web application, and it is not uncommon to use a validating parser to load this XML. Parser validation requires a schema or DTD to validate, and the URL for a schema / DTD file is often included in XML. Thus, some parsers will try to download the schema file from the Internet to check the XML, and this can take a long time to connect to the Internet. Moreover, some parsers fail silently and simply do not validate XML, possibly after a rather long timeout. Sorry for the ambiguity regarding "some parsers", etc., but if the XML is loaded using the libraries used inside your webapp, they can use the JVM XML parser, any possible version of Xerces, any possible version for JDOM, etc. .... and even the most different libraries can use different parsers.

However, if the problem is with the connection, it is easier to see it with "netstat -anlp | grep java" (your tomcat has * nix environment, otherwise it should be "netstat -ano" on the windows) and looks for what outgoing connection it is trying to make your cat. There you can see DB connections, as well as outgoing (usually http) connections that are looking for schemes or other things.

+5
source

If you use Tomcat 7.0.x, it can scan the classpath to detect annotations. If you have a lot of jars / classes, this can be a problem.

As Simon says, accepting and analyzing multiple thread dumps is a good way to get started.

If you are not using the latest version of Tomcat, try updating and checking out the conf / catalina.properties file for tips on how to reduce the number of checked jars.

+4
source

During deployment, you should take a few dumps of threads (all the better) and analyze them. Look for blocks, expectations, etc. Thread Dump Analyzer may be helpful.

+3
source

This may apply to this JDK ERROR

I read this article, Tomcat7 starts too late on Ubuntu 14.04 x64 and solved my problem.

Try resolving it with Replacing securerandom.source = file: / dev / urandom with securerandom.source = file: / dev /./ urandom in $ JAVA_PATH / jre / lib / security / java.security

+1
source

I found that I had a big delay when deploying a web application on Tomcat8. I had three database connection pools configured in my context.xml file in WAR. Each connection pool had an initial number of 10 connections, so Tomcat created 30 database connections at startup. I found that setting each pool for 1 initial connection in my test system improved the deployment time from about 3 minutes to 22 seconds.

0
source

Add tomcat7/bin your setenv.sh working directory below:

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

-3
source

Source: https://habr.com/ru/post/917222/


All Articles