Comparison and optimization of three operation modes (bio, NiO and APR) of Tomcat Connector

Posted by Tezread on Tue, 19 Oct 2021 08:26:47 +0200

Operation mode

Comparison and optimization of three operation modes (bio, NiO and APR) of Tomcat Connector.

org.apache.coyote.http11.Http11Protocol: BIO
org.apache.coyote.http11.Http11NioProtocol: NIO
org.apache.coyote.http11.Http11Nio2Protocol: NIO2
org.apache.coyote.http11.Http11AprProtocol: APR

BIO

A thread processes a request. Disadvantages: when the concurrency is high, the number of threads is large and resources are wasted. Tomcat7 or below, which is used by default in Linux system.

NIO

Using Java asynchronous IO processing, you can process a large number of requests through a small number of threads. Tomcat8 uses this method by default in Linux systems. Tomcat7 must modify the Connector configuration to start:

<Connector port="8080" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           connectionTimeout="20000"
		   redirectPort="8443"/>

NIO2 mode after Tomcat8:

<Connector  port="8080"
            protocol="org.apache.coyote.http11.Http11Nio2Protocol"
            connectionTimeout="20000"
		    redirectPort="8443"/>

APR

That is, Apache Portable Runtime, which solves io blocking from the operating system level. Tomcat7 or Tomcat8 is started in Win7 or above systems. This method is used by default. If apr and native are installed in Linux, Tomcat supports apr when it is started directly.

Connection pool

Default:

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>

Amend to read:

<Executor 
    name="tomcatThreadPool" 
    namePrefix="catalina-exec-"
    maxThreads="500" 
    minSpareThreads="100" 
    prestartminSpareThreads = "true"
    maxQueueSize = "100"
/>

Parameter interpretation:

  • maxThreads, the maximum concurrent number, is set to 200 by default. It is generally recommended to be 500 ~ 800. It is determined according to hardware facilities and services
  • minSpareThreads: the number of threads created during Tomcat initialization. The default setting is 25
  • prestartminSpareThreads: initialize the parameter value of minSpareThreads during Tomcat initialization. If it is not equal to true, the value of minSpareThreads will have no effect
  • maxQueueSize, the maximum number of waiting queues. If it exceeds, the request will be rejected

Default link parameter configuration:

<Connector 
    port="8080" 
    protocol="HTTP/1.1" 
    connectionTimeout="20000" 
    redirectPort="8443" 
/>

Amend to read:

<Connector  executor="tomcatThreadPool"
            port="8080"
            protocol="org.apache.coyote.http11.Http11Nio2Protocol"
            connectionTimeout="20000"
		    redirectPort="8443"/>

Parameter interpretation:

  • Protocol, Tomcat 8, setting nio2 is better: org.apache.coyote.http11.Http11Nio2Protocol
  • Protocol, Tomcat 6 and 7: org.apache.coyote.http11.http11nio protocol
  • enableLookups to disable DNS queries
  • acceptCount specifies the number of requests that can be put into the processing queue when all available threads for processing requests are used. Requests exceeding this number will not be processed. The default setting is 100
  • maxPostSize, a POST submission method with the FORM URL parameter, limits the maximum size of the submission. The default is 2097152 (2 megabytes), and its unit is bytes. 10485760 is 10M. If you want to disable the restriction, you can set it to - 1
  • acceptorThreadCount, the number of threads used to receive connections. The default value is 1. Generally, this refers to the time when the server needs to be changed because the server is a multi-core CPU. If it is a multi-core CPU, it is generally configured as 2

port configuration

The Tomcat server needs to be configured with three ports to start. These three ports are enabled by default during installation. When multiple Tomcat services are to be run, these three ports need to be modified.

<!-- port-1 OK, identify random -->
<Server port="-1" shutdown="SHUTDOWN">
<!-- Access port, must be configured -->
<Connector  port="8080"
            protocol="org.apache.coyote.http11.Http11Nio2Protocol"
            connectionTimeout="20000"
		    redirectPort="8443"/>
<!-- to configure Apache Use, if used Nginx Just comment it out -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

JVM optimization

The memory model of Java is divided into:

  • Young, young generation (easy to be GC). The young area is divided into three parts: Eden area and two Survivor areas with the same size. In the Survivor area, only one of them is used at a certain time, and the other is reserved for copying objects during garbage collection. When the young area becomes full, the minor GC will move the surviving objects to the idle Survivor area. According to the strategy of the JVM, After several garbage collections, objects that still survive will be moved to the Tenured interval.

  • Tenured, lifelong generation. The tenured area mainly stores objects with a long life cycle, generally old objects. When some objects are copied and transferred in Young for a certain number of times, the objects will be transferred to the tenured area. Generally, if the application level cache is used in the system, the objects in the cache will often be transferred to this area.

  • Perm, permanent generation. It mainly saves class, method and file objects. Generally, the space in this department will not overflow unless many classes are loaded at one time. However, when it comes to the hot deployed application server, it sometimes encounters the error of java.lang.outofmemoryerror: permgen space. The main reason for this error may be that it is redeployed every time, but after redeployment, The class of class is not unloaded, which causes a large number of class objects to be saved in perm. In this case, generally, restarting the application server can solve the problem.

Linux modifies the / tomcat/bin/catalina.sh file and adds the following information to the first line of the file.

If the sub memory is 8G, the general PermSize configuration is mainly to ensure the stability of the system:

JAVA_OPTS="-Dfile.encoding=UTF-8 -server -Xms6144m -Xmx6144m -XX:NewSize=1024m -XX:MaxNewSize=2048m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:+DisableExplicitGC"

Parameter Description:

-Dfile.encoding: Default file encoding
-server: Indicates that this is the configuration applied to the server, JVM There will be special treatment inside
-Xmx1024m: set up JVM The maximum available memory is 1024 MB
-Xms1024m: set up JVM The minimum memory is 1024 m. This value can be set with-Xmx Same to avoid every time garbage collection is completed JVM Reallocate memory.
-XX:NewSize: Set younger generation size
-XX:MaxNewSize: Set the maximum younger generation size
-XX:PermSize: Set permanent generation size
-XX:MaxPermSize: Set maximum permanent generation size
-XX:NewRatio=4: Set up the younger generation (including Eden And two Survivor Area) to lifetime generation (excluding permanent generation). If it is set to 4, the ratio of the younger generation to the lifelong generation is 1:4, and the younger generation accounts for 1 of the whole stack/5
-XX:MaxTenuringThreshold=10: Set the maximum age of garbage. The default is 15. If it is set to 0, younger generation objects do not pass through Survivor Area, directly into the elderly generation. For applications with more elderly generations, efficiency can be improved. If you set this value to a larger value, younger generation objects will Survivor The area is copied for many times, which can increase the survival time of the object in the younger generation and increase the probability of being recycled in the younger generation.
-XX:+DisableExplicitGC: This will ignore manual calls GC The code makes System.gc() The call will become an air conditioner and will not trigger any at all GC

Topics: Java Linux Tomcat