JMJ CLOUD
  • Home
  • Projects
  • Blog
  • About Us
  • Contact Us

Our Blog

Tuning Tomcat for APEX/ORDS in Production

1/14/2017

5 Comments

 

Introduction

Picture
In a previous post Tuning GlassFish for APEX/ORDS in Production I described the steps to configure ORDS and GlassFish for production use. In this post, I will turn my attention to Tomcat and see what needs to be done to get Tomcat production ready for ORDS and APEX. I will focus purely on the Tomcat configurations as I already covered the ORDS side in the previous post.

Like GlassFish, out of the box, Tomcat comes configured for use in a development environment. You will see many of the same limitations as Glassfish when considering production use:
  • Tomcat will be running in development mode (which incurs an overhead in checking to see if code has changed)
  • If you have more than 1 CPU, you will not be taking advantage of it
  • Tomcat will only assign 512m of ram to the JVM (and ORDS), even if you have more available
  • Logging will be set to FINE and INFO, adding a logging burden to Tomcat
  • You are in danger of timing out on large file uploads

Setting the Scene

I will use the same example as I did previously. I am going to assume an actively used system with 250 users and an anticipated peak load of 50 sessions. We are assuming that only 50 of these 250 users could be clicking on an APEX button (or making and Ajax request) at exactly the same time requiring all 50 JDBC connections. We are assuming a normal load of 20 concurrently active users. I am going to assume we have a dedicated web server running ORDS and Tomcat with 4GB RAM and 1 Quadcore CPU. The configurations discussed here assume Tomcat version 8.5.6.

Tomcat Configurations

Follow your normal routine for downloading and installing the JDK and Tomcat. I will be calling out the name of the configuration file that needs to be created/changed as well as the setting within the file. I will assume $CATALINA_HOME refers to the root of your Tomcat install folder. So if you installed Tomcat at /opt/tomcat you would see sub-directories of bin, conf, logs etc. making $CATALINA_HOME = /opt/tomcat

Logging
Configuration File: $CATALINA_HOME/conf/logging.properties
Change all occurrences of FINE and INFO to SEVERE

JVM Options
To pass JVM options to Tomcat on startup, you should create a new file called $CATALINA_HOME/bin/setenv.sh

Add the following values:
export CATALINA_OPTS="$CATALINA_OPTS -Xms1536m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx1536m"
export CATALINA_OPTS="$CATALINA_OPTS -server"
Note: If you are running JDK7, you can also set PermSize and MaxPermSize. Note: PermSize and MaxPermSize not applicable for Java 8.
export CATALINA_OPTS="$CATALINA_OPTS -XX:PermSize=256m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxPermSize=256m"

Main Tomcat Server Configurations
We are going to be configuring Tomcat on Port 8080.
Configuration File: $CATALINA_HOME/conf/server.xml

Add the following under the Catalina Service:

    
Notes:
  • acceptorThreadCount - The number of threads to be used to accept connections. Increase this value on a multi CPU Core machine.
  • acceptCount - The maximum queue length for incoming connection requests when all possible request processing threads are in use. Any requests received when the queue is full will be refused. Set to 10 to protect server from getting overloaded.
  • maxConnections - The maximum number of connections that the server will accept at any given time. When this number has been reached, the server will accept, but not process, one further connection. Connections are passed on to available threads to perform the actual work.
  • maxThreads - The maximum number of request processing threads to be created by a connector, which therefore determines the maximum number of simultaneous requests that can be handled.
  • minSpareThreads - The minimum number of threads always kept running waiting for new requests.
  • connectionTimeout - The number of milliseconds a connector will wait, after accepting a connection, for the request URI line to be presented.
  • disableUploadTimeout - Set to false and use the value in connectionUploadTimeout as the upload timeout.
  • connectionUploadTimeout - Specifies the timeout, in milliseconds, to use while a data upload is in progress. This only takes effect ifdisableUploadTimeout is set to false.

Note: The threads described above do not impact JDBC connection pooling, which ORDS is handling for us. ORDS is protecting (or throttling) the JDBC connections Tomcat is organizing the web connections. If we assume the MaxLimit JDBC connection setting in ORDS is 50 then we have a healthy overhead of connections over to queue any users we have over 50.

Conclusion

The above settings are a guideline for configuring Tomcat to run ORDS in a fictitious production environment. As with all things performance, you will still need to go through the exercise of adding load to your system and finding the right settings for your hardware, users, data etc. The good news is, you now know which levers to pull!
5 Comments
Gaspar
1/16/2017 12:47:51 am

You mentioned that tomcat will be running in development mode (which incurs an overhead in checking to see if code has changed) but didn't provide any info on this.
Can you please elaborate on the matter?


Thanks
Gaspar

Reply
Jonathan Dixon
1/16/2017 07:07:14 am

Hi Gaspar,

Thanks for pointing that out. I was referring to the behavior where Tomcat polls for changes to class files and reloads them if they have change. As your production code should not be changing for ORDS, you can disable this with a Context section in server.xml. Something like the following:

<Context path="/ords" reloadable="fals">

Jon

Reply
Shaun
1/16/2017 03:29:08 am

Hi

What changes would you make if you were to put Apache in front of Tomcat and only connect to Tomcat via AJP?

Regards,

Reply
Jonathan Dixon
1/16/2017 06:54:06 am

Hi Shaun,

Not sure on the AJP side but if you had Apache fronting Tomcat over HTTP, you would add something like the following to the Connector config in server.xml

<Connector port="8080" protocol="HTTP/1.1"
scheme="https"
proxyName="cloudnueva.com"
proxyPort="443"
secure="true"
redirectPort="8443" />

Reply
Christoph link
1/16/2017 09:39:27 am

Great post! Thanks for the info.

Reply

Your comment will be posted after it is approved.


Leave a Reply.

    RSS Feed

    Popular Posts

    - APEX Dog Food
    - Cloud ERP & APEX Mashup
    - Modernizing EBS with APEX
    - Easy APEX_WEB_SERVICE
    - Running APEX in RDS
    - ORDS What & Why?

    Categories

    All
    APEX
    AWS
    Fusion Cloud ERP
    INTEGRATION
    OCI
    ORDS
    PaaS
    RAD
    REST
    SOAP

    Archives

    January 2021
    October 2020
    September 2020
    June 2020
    May 2020
    April 2020
    February 2020
    January 2020
    October 2019
    September 2019
    August 2019
    July 2019
    June 2019
    April 2019
    March 2019
    February 2019
    January 2019
    December 2018
    November 2018
    October 2018
    September 2018
    August 2018
    July 2018
    June 2018
    May 2018
    April 2018
    March 2018
    February 2018
    January 2018
    September 2017
    August 2017
    July 2017
    June 2017
    February 2017
    January 2017
    December 2016
    November 2016
    October 2016
    September 2016
    August 2016
    July 2016

Company

About
Contact
Blog
  • Home
  • Projects
  • Blog
  • About Us
  • Contact Us