Pivotal Knowledge Base

Follow

Java Web Applications Slow Startup or Failing

Symptoms

You have a Java web application (Java Web, Grails, Spring, etc...) which starts up very slowly or fails indicating that it did not begin accepting for connections.

Cause

When a Java web application is deployed to PWS, the Java build pack configures an instance of Apache Tomcat where the Java web application will be deployed. Recent versions of Tomcat (7 and 8) rely on Java's SecureRandom class to provide random values for things like session ids.  Depending on the JVM and environment, the startup of Tomcat can be delayed if SecureRandom does not have access to sufficient entropy.  This will in turn cause your application to start slow and, if it's slow enough, fail with the error instance failed to start accepting connections.

Resolution

The recommended workaround to this problem is to add -Djava.security.egd=file:/dev/./urandom to your list of JVM options.  This instructs the JVM to use a non-blocking entropy source (i.e. /dev/urandom) instead of the default blocking entropy source (i.e. /dev/random).

This can be done in your application by setting the JAVA_OPTS environment variable either via your application's manifest.yml file or with the cf set-env command.

Ex:  manifest.yml

---
applications:
- name: <your-app>
  memory: 512M
  instances: 1
  path: <path-to-your-app>
  env:
    JAVA_OPTS: -Djava.security.egd=file:///dev/urandom

Ex: cf set-env

 $ cf set-env <your-app> JAVA_OPTS "-Djava.security.egd=file:///dev/urandom"

It is worth mentioning that some believe that this workaround can result in your application receiving data that is less random.  There are varying opinions on this matter and how it might affect an application (see the See Also section below if you have concerns).  For the purposes that Tomcat needs this random data (session id generation), we do not believe that this will weaken the security of your application.

Additional Information

While it has a limited affect because the maximum value is capped, it is worth mentioning the -t argument to cf push, which increases the amount of time that the application is given to start, can also be used as a possible workaround to this issue.  While this does not address the root cause or help to make the application start faster, it does provide the application with more time to start which can prevent the instance failed to start accepting connections errors.  Because this does not address the root cause, we only recommend using this work around if the first one is not an option for you.

See Also

Additional information about this problem in relation to Apache Tomcat can be found here.

Additional information regarding /dev/random and /dev/urandom.

A more general explanation of this issue and how it relates to randomness in multi-tenant systems can be found on the Pivotal Blog here.

Comments

Powered by Zendesk