First, summarize the previous day’s learning

From the performance testing section on “Day 3,” we learned that some of the important metrics that determine performance testing are:

U throughput

U Responsetime

U Cpuload

U MemoryUsage

We also optimized Apache in the third day to optimize the readings of the above four core indicators, so our Apache has been tuned, and our Tomcat has also been adjusted accordingly. When you finish this course, your cat will really “fly”, so please watch carefully. This article is a tribute to the author who wrote “How Tomcat can handle 1000 users”, and an extension of the original article, which was solved by applying the knowledge of the original to two related projects:

1) Bear more concurrent users

2) Achieved good performance and improvement (average system performance increased by 20 times, extreme a transaction up to 80 times).

It’s also worth noting that the cat we were working on was running on a 32-bit machine, which meant that our JVM was limited to 2GB of memory and was already flying… If you run this cat on a 64-bit machine… You can imagine, will get what kind of effect? Please set it in detail below!

 

Two, all based onJVM (memory) optimization

2.1 32A comparison of the JVM in a 64-bit operating system

We generally use a 32-bit Windows system, which leads to a serious problem: 32-bit Windows system memory limitation, the following is a comparison of the table:

The operating system

Operating system bit

Memory limit

The solution

Winxp

32

4GB

Super rabbit

Win7

32

4GB

This can be done by setting /PAE

Win2003

32

It can go from 4GB to 16GB

Win2003 Advanced Server must be installed and sp2 must be installed

Win7

64

unlimited

The system can hold as much memory as the machine can hold

Win2003

64

unlimited

The system can hold as much memory as the machine can hold

Linux

64

unlimited

The system can hold as much memory as the machine can hold

Unix

64

unlimited

The system can hold as much memory as the machine can hold

With the above problems solved, we have a new problem: the memory limit of the JVM on 32-bit systems cannot exceed 2GB, even if your machine has 8GB-16GB of memory on Windows 2003 Advanced Server, and your JAVA can only use 2GB of memory.

In fact, I always recommend that you use Linux or Mac operating system, and install 64-bit, because we must be developing, not playing games, and Java is from Unix to Unix (Linux is just Unix running on PCS).

So a lot of developers running on win32 bit system more even in the production environment will deploy Win32 bit system, then your Tomcat to optimize, you have to pay attention to some skills. Neither system memory nor JVM is limited to 2GB on 64-bit operating systems.

The optimization of Tomcat is divided into two parts:

U The optimization parameter in the Tomcat startup command line is JVM optimization

U optimization of Tomcat container parameters (much like ApacheHttp Server)

This section starts with the optimization parameters in the Tomcat startup command line.

Tomcat runs on top of the JVM first, because its startup is really just a Java command line. First we need to tune the Java startup command line.

Note that:

The JVM optimizations discussed here are based on Oracle Sun JDK 1.6 and are not applicable to other JDKS or lower JDKS.

Tomcat 2.2Start optimization of row parameters

The Tomcat startup parameters are in the Tomcat installation directory \bin. If you are running Linux, you need to modify the catalina.bat file. Open the file, usually the file header is a pile of comment text wrapped in ##, find the last paragraph of the comment text like:

# $Id: catalina.sh 522797 2007-03-27 07:10:29Z fhanik $

# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

 

# OS specific support.  $var _must_ be set to either true or false.

Type a return and add the following parameters

Tomcat startup parameters in Linux

export JAVA_OPTS=”-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC  -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m  -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true “

Tomcat startup parameters in Windows

set JAVA_OPTS=-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC  -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m  -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true

There are so many parameters in the tomcat startup command. Of course, these parameters are only for my machine, and may not be suitable for you, especially the value (value) after the parameter needs to be set according to your actual situation.

Parameter Description:

U – server

I don’t care what your reason is, as long as your Tomcat is running in production environment, this parameter must be added to me

Because Tomcat is run in java-client mode by default, server means that your Tomcat is run in real Production mode, which means that your Tomcat running in server mode will have: Higher concurrent processing capacity, faster and more powerful JVM garbage collection mechanism, can achieve more load and throughput… More… And more…

If you don’t add the -server, you’ll need a spanking.

U – Xms -xmx

If the JVM memory is set to the same value, it is best to set Xms and Xmx to the same value. Some people say that Xms is the minimum value and Xmx is the maximum value. Human nature? Science? You’re big.

Consider this scenario:

As a system gets more and more concurrency, its memory usage goes up, it goes up to a point where it can’t go up, it starts to fall back, and you don’t think of this fall as a good thing, it’s a big boom and bust, and the price it pays when the memory goes down is the CPU starts running at high speed to do garbage collection, It can even cause your system to “jam” when you’re doing something nice and suddenly the page dies for a few seconds or more because the JVM is doing garbage collection.

So we set the two to be the same at the beginning, so that Tomcat can maximize the efficiency of the system at startup. This is the same principle as the minpool size and maxPool size in the JDBCConnection pool need to be set to the same number.

How do I know if my JVM can use maximum? Head? No way!

To set the maximum memory (Xmx) value, open a command line and type the following command:

The JDK version is displayed correctly, indicating that you can use this value. Doesn’t it mean you can use up to 2GB of ram on a 32-bit system? That is, 2048 meters. Let’s try it

Is that ok? Can’t be! Don’t say 2048 meters, let’s go smaller, how about 1700meters

Even 1700m is not acceptable, let alone 2048m, 2048m is just a theoretical number, let’s say I have several machines here, some machines are ok with -XMX1800, some machines can only reach -XMX1500m.

-xms = -xmx = -xmx = -xmx = -xmx

U – Xmn

Set the size of the young generation to 512 MB. Total heap size = young generation size + Old generation size + persistent generation size. The permanent generation has a fixed size of 64m, so increasing the young generation will reduce the size of the old generation. This value has a significant impact on system performance. Sun officially recommends setting it to 3/8 of the entire heap.

U – Xss

The stack size is set for each thread. Depending on your program, see how much memory a thread takes up, how many threads may be running at the same time, etc. Generally, it is not easy to set more than 1M, otherwise out ofmemory may occur.

U – XX: + AggressiveOpts

As its name implies, with this parameter enabled, your JVM will use the latest optimization technology (if any) whenever the JDK version is updated

U – XX: + UseBiasedLocking

With an optimized thread lock, we know that in our AppServer, each HTTP request is a thread, some requests are short, some requests are long, there will be queuing, and even thread blocking. This optimized thread lock will automatically optimize the allocation of thread processing within your AppServer.

U – XX: PermSize = 128 m – XX: MaxPermSize = 256 m

The JVM uses -xx :PermSize to set the initial value of non-heap memory, which defaults to 1/64 of physical memory.

When exporting files with a large amount of data, make sure to set these two values; otherwise, memory overflow errors may occur.

The maximum non-heap memory size is set by XX:MaxPermSize. The default is 1/4 of the physical memory.

So, if physical memory is 4GB, then 1/64 is 64MB, which is the default value of PermSize, which is the initial memory size of eternal generation.

A quarter is 1024MB, which is the default size of MaxPermSize.

U – XX: + DisableExplicitGC

No explicit calls to system.gc () are allowed in program code. I have seen two extreme projects that manually call system.gc () every time at the end of a DAO operation. I think this can solve their out ofmemory problems, and the cost is a serious decrease in System response time, just like the principle I explained in Xms,Xmx. Calling GC in this way will cause the JVM of the system to fluctuate wildly and performance will not be affected.

U – XX: + UseParNewGC

The use of multithreaded parallel recycling for the young generation, so fast.

U – XX: + UseConcMarkSweepGC

CMS GC, a feature available only in JDK1.5 and later, uses GC estimation triggers and Heap occupancy triggers.

We know that frequent GC can cause huge ups and downs in the JVM, which can affect the efficiency of the system. Therefore, with the CMS GC, the response time of each GC can be very short. For example, after using the CMS GC, jprofiler observed that GC was triggered many times. Each GC takes only a few milliseconds.

U – XX: MaxTenuringThreshold

Set the maximum garbage age. If set to 0, the young generation object passes through the Survivor zone and goes directly to the old generation. For the older generation of more applications, can improve efficiency. If this value is set to a large value, the young generation object will be copied multiple times in the Survivor zone, which increases the lifetime of the object in the young generation and increases the probability that it will be recycled in the young generation.

This value is an ideal value based on local Jprofiler monitoring and cannot be copied.

U – XX: + CMSParallelRemarkEnabled

In the case of UseParNewGC, minimize Mark’s time

U – XX: + UseCMSCompactAtFullCollection

In the case of concurrent GC, memory Fragmention is prevented and live objects are collated to reduce memory fragmentation.

U – XX: LargePageSizeInBytes

Specifies the paging page size for the Java Heap

U – XX: + UseFastAccessorMethods

Get,set methods are converted to native code

U – XX: + UseCMSInitiatingOccupancyOnly

Indicates that concurrent Collector starts collection only after OldGeneration has used the initialized ratio

U – XX: CMSInitiatingOccupancyFraction = 70

CMSInitiatingOccupancyFraction, this parameter has great skills, Basically satisfy (-xmx – Xmn) * (100 – CMSInitiatingOccupancyFraction) / 100 > = Xmn wouldn’t have promotion failed. -xmx is 6000 in my application, Xmn is 512, then the -xmx – Xmn is 5.488 billion, 5.488 billion, is the old generation CMSInitiatingOccupancyFraction = 90 shows that older generation to 90% began to perform in full of the old generation of concurrent garbage collection (CMS), At this time, the remaining 10% space is 5488*10%=548 MB, so even if all objects in Xmn (i.e., 512 MB in the young generation) are moved to the old generation, 548 MB space is enough, so as long as the above formula is full, there will not be promotion failed in garbage collection.

Therefore, the setting of this parameter must be associated with Xmn.

U – Djava. Awt. Headless = true

This parameter is usually used last. The full parameter is used for this purpose. Sometimes we use charting tools in our J2EE projects such as: Jfreechart is used to output GIF/JPG streams in web pages. Under the WinodWS environment, our app Server will not encounter any problems in the output of graphics. However, in Linux/Unix, there is often an exception that causes your image to display well in Windows development but not in Linux/Unix, so this parameter is used to avoid this.

The above configuration can basically achieve:

U System response time increases

U JVM reclaim speeds increase without affecting system responsiveness

U Maximize memory utilization of the JVM

U Thread blocking is minimized

Tomcat 2.3In-container optimization

We have optimized the Tomcat startup commands to increase the number of AVAILABLE JVMS, garbage collection efficiency, thread blocking, and system response efficiency. There is another important indicator that we did not optimize, which is throughput.

Remember we said on day 3 that the system itself can handle 1000, and you didn’t optimize and configure it so that it can only handle 25 by default. So let’s look at optimization within the Tomcat container.

Open the tomcat installation directory \conf\server. XML file and navigate to this line:

The < Connector port = “8080” protocol = “HTTP / 1.1”

This line is where our Tomcat container performance parameters are set. It usually has a default value. These default values are far from sufficient for our use.

The < Connector port = “8080” protocol = “HTTP / 1.1”

          URIEncoding=”UTF-8″  minSpareThreads=”25″ maxSpareThreads=”75″

          enableLookups=”false” disableUploadTimeout=”true” connectionTimeout=”20000″

          acceptCount=”300″  maxThreads=”300″ maxProcessors=”1000″ minProcessors=”5″

          useURIValidationHack=”false”

                                               compression=”on” compressionMinSize=”2048″

                                               compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain”

               redirectPort=”8443″

/>

It’s so big…

It doesn’t matter. Explain them one by one

U URIEncoding = “utf-8”

Make It convenient for Tomcat to parse urls for files with Chinese names, unlike Apache which has mod_encoding and manual compilation

U maxSpareThreads

MaxSpareThreads means that if there are more idle threads than the set number, these threads are aborted, reducing the total number of threads in the pool.

U minSpareThreads

Minimum number of standby threads, the number of initialized threads when Tomcat starts.

U enableLookups

This function is set to off like HostnameLookups in Apache.

U connectionTimeout

ConnectionTimeout Indicates the timeout time of the network connection in milliseconds.

U maxThreads

MaxThreads Tomcat uses threads to process each request it receives. This value represents the maximum number of threads that Tomcat can create, which is the maximum number of concurrent requests.


U acceptCount

An acceptCount is the size of an acceptCount queue that will refuse connection when maxThreads are full


U maxProcessors minProcessors

In Java, a thread is a path through which a program runs. It is a piece of code that can run independently of other control threads in a program. They share the same address space. Multithreading helps programmers write efficient programs that maximize CPU utilization and keep idle time to a minimum, thus accepting more requests.

Usually around 1000 for Windows and 2000 for Linux.

U useURIValidationHack

Let’s take a look at tomcat source code:

security

        if (connector.getUseURIValidationHack()) {

            String uri = validate(request.getRequestURI());

            if (uri == null) {

                res.setStatus(400);

                res.setMessage(“Invalid URI”);

                throw new IOException(“Invalid URI”);

            } else {

                req.requestURI().setString(uri);

                // Redoing the URI decoding

                req.decodedURI().duplicate(req.requestURI());

                req.getURLDecoder().convert(req.decodedURI(), true);

            }

        }

As you can see, if you set the useURIValidationHack to “false”, you can save money by reducing its unnecessary checking of some urls.

U enableLookups = “false”

To eliminate the impact of DNS queries on performance, you can disable DNS queries by changing the enableLookups parameter in the server. XML file.

U disableUploadTimeout

Similar to KeeyAlive in Apache

U Configure Gzip compression (HTTP compression) for Tomcat

compression=”on” compressionMinSize=”2048″             

compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain”

HTTP compression can greatly improve the speed of browsing websites. Its principle is that after the client requests a web page, the web file is compressed from the server and then downloaded to the client. The browser of the client is responsible for decompression and browsing. Compared to the normal browsing process of HTML,CSS,Javascript, Text, it can save about 40% of the traffic. More importantly, it can be dynamically generated, including CGI, PHP, JSP, ASP, Servlet,SHTML and other output pages can also be compressed, compression efficiency is amazing.

1) Compression =”on” To enable compression

2)compressionMinSize=”2048″ Enable compressed output content size, which defaults to 2KB

3)noCompressionUserAgents=” Gozilla, Traviata “For the following browsers, compression is disabled

4)compressableMimeType=”text/ HTML,text/ XML

And finally, don’t forget to do the same for port 8443, because if we use HTTPS, we’re going to use port 8443, right?

<! –enable tomcat ssl–>

The < Connector port = “8443” protocol = “HTTP / 1.1”

               URIEncoding=”UTF-8″  minSpareThreads=”25″ maxSpareThreads=”75″

          enableLookups=”false” disableUploadTimeout=”true” connectionTimeout=”20000″

          acceptCount=”300″  maxThreads=”300″ maxProcessors=”1000″ minProcessors=”5″

          useURIValidationHack=”false”

                    compression=”on” compressionMinSize=”2048″

                    compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain”

                SSLEnabled=”true”

           scheme=”https” secure=”true”

           clientAuth=”false” sslProtocol=”TLS”

           keystoreFile=”d:/tomcat2/conf/shnlap93.jks” keystorePass=”aaaaaa”

      />

All the Tomcat optimizations have been added. Combined with the Apache performance optimizations in Day 3, we were able to “fly” the architecture. Of course, there are any database optimization steps mentioned here, but with these two steps alone, our system has improved a lot.

Take a real example: in the last project, after four rounds of performance testing, problems were located in the first round, optimized apache+ Tomcat/Weblogic in the second round, optimized cluster in the third round, and optimized SQL and Codes in the fourth round.

By the time we got to round two, how many times had we improved? Let’s take a look at a screenshot of loaderRunner:





The first column on the left is the first round of stress test reports without any tuning.

The column on the right is the pressure test report obtained after Apache optimization and Tomcat optimization.

How important are Apache and Tomcat? If you add the following code, SQL tuning, database tuning… So I had an extreme case in my last project where the single transaction performance (throughput, response time) increased by 80 times.