From the performance test section on the third day, we learned several important indicators that determine the performance test. They are:
Ü Throughput
Ü responsetime
Ü cpuload
Ü memoryusage
We also made some optimizations to Apache in the third day of study, so that it can optimize the reading of the above four core indicators, so our Apache tuning, our tomcat has also made some corresponding adjustments. After completing this course, your "kitten" will actually "fly", so please read it carefully, this article is an extension of the original article, on the one hand, to the author who once wrote "How Tomcat can afford 1000 users, the problem is solved after the original article knowledge is used in two major projects:
1) more concurrent users allowed
2) excellent performance and improvement (the average system performance is increased by 20 times, and the extreme transaction rate is 80 times ).
In addition, the "kitten" we used in the project was running on a 32-bit host, that is, our JVM was limited by a maximum of 2 GB of memory, all of them have been "Flying ...... If you run this kitten on a 64-bit host "...... What kind of results can we imagine? Please set it in detail below!
Ii. All JVM-based (memory) optimizations 2.1 comparison between a 32-bit operating system and a JVM in a 64-bit Operating System
Our general developers basically use 32-bit Windows systems, which leads to a serious problem: 32-bit Windows system memory restrictions, here is a comparison table:
Operating System |
Operating System bits |
Memory limit |
Solution |
WINXP |
32 |
4 GB |
Super Rabbit |
Win7 |
32 |
4 GB |
You can set/PAE |
Win2003 |
32 |
It can exceed 4 GB to 16 GB |
Win2003 Advanced Server must be installed and SP2 patch required |
Win7 |
64 |
Unlimited |
How much memory can be inserted by the machine, and how much memory can be supported by the system |
Win2003 |
64 |
Unlimited |
How much memory can be inserted by the machine, and how much memory can be supported by the system |
Linux |
64 |
Unlimited |
How much memory can be inserted by the machine, and how much memory can be supported by the system |
UNIX |
64 |
Unlimited |
How much memory can be inserted by the machine, and how much memory can be supported by the system |
After the above problem is solved, we have encountered a new problem. In 32-bit systems, JVM has a limit on memory: 2 GB memory cannot be exceeded, even if your machine is equipped with 8 gb-16 GB memory under win2003 Advanced Server, your Java can only use 2 GB memory.
In fact, I have always wanted to recommend you to use Linux or Mac operating systems and install 64-bit, because we must develop and use it instead of playing games, java is derived from Unix (Linux is only Unix running on PC ).
Therefore, many developers run on Win32 bit systems. Even more, Win32 bit systems are deployed in the production environment. Therefore, you must be skillful in optimizing tomcat.In 64-bit operating systems, both the system memory and JVM are not subject to the limit of 2 GB.
Tomcat optimization is divided into two parts:
Ü optimization parameters in the Tomcat startup command line are JVM Optimization
Ü Optimization of Tomcat container parameters (this is similar to apachehttp server)
This section describes the optimization parameters in the Tomcat startup command line.
Tomcat runs on the JVM first, because its startup is actually just a Java command line. First, we need to tune the Java startup command line.
Note that:
The JVM optimization discussed here is based on Oracle sun jdk1.6 and later versions. Other JDK or lower version JDK is not applicable.
2.2 Optimization of Tomcat startup line parameters
Tomcat startup parameters are located in the installation directory \ bin directory of Tomcat. If you are a Linux operating system, it is Catalina. sh file. If you are a Windows operating system, you need to change it to Catalina. BAT file. Open the file. Generally, the file header is a pile of comments wrapped in #. Find the last part of the comments, for example:
# $ ID: Catalina. Sh 522797 07: 10: 29z fhanik $ #----------------------------------------------------------------------------- # OS specific support. $ VaR _ must _ be set to either true or false. |
Press enter and add the following parameters.
Tomcat startup parameters in Linux
Export java_opts = "-server-xms1400m-xmx1400m-xss512k-XX: + bytes-XX: + usebiasedlocking-XX: permsize = 128 M-XX: maxpermsize = 256 m-XX: + disableexplicitgc-XX: maxtenuringthreshold = 31-XX: + useconcmarksweepgc-XX: + useparnewgc-XX: + cmsparallelremarkenabled-XX: + signature-XX: Signature = 128 M-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 = 128 M-XX: maxpermsize = 256 m-XX: + disableexplicitgc-XX: maxtenuringthreshold = 31-XX: + useconcmarksweepgc-XX: + useparnewgc-XX: + cmsparallelremarkenabled-XX: + signature-XX: Signature = 128 M-XX: + usefastaccessormethods-XX: + usecmsinitiatingoccupancyonly-djava. AWT. headless = true |
There are a lot of parameters above. Some people may have written that no Tomcat startup command has been added with so many parameters. Of course, these parameters are only on my machine and may not be suitable for you, in particular, the value after the parameter needs to be set according to your actual situation.
Parameter description:
Ü-Server
For whatever reason, as long as your Tomcat is running in the production environment, this parameter must be added to me.
Because Tomcat runs in the Java-client mode by default, server means that your Tomcat runs in the real production mode, this means that your Tomcat will have a larger and higher concurrent processing capability and a faster and more advanced JVM garbage collection mechanism when running in server mode, you can get more load and throughput... More... And more...
Y, please remember. Otherwise, this-server will not be added. It is about to beat your ass.
Ü-XMS-xmx
That is, the JVM memory is set. It is the best practice to set the XMS and xmx values to the same value. Some people say that XMS is the minimum value and xmx is the maximum value, which is more user-friendly and scientific. Human nature? Science? Your head.
Consider the following scenario:
As the number of concurrent jobs increases, the memory usage of a system increases gradually, and it cannot rise to the highest point. It starts to fall back. Do not consider this fall as a good thing, when the memory falls back, the price it pays is that the CPU starts to run at high speed for garbage collection. At this time, serious problems may even cause your system to get stuck, which means you are doing well, suddenly, the webpage is several or even dozens of seconds as it is dead, because the JVM is garbage collection.
So we set the two to the same in the beginning, so that Tomcat can maximize the system efficiency by making full use of the parameters at startup, this principle is the same as that of the minpool size and maxpool size in the jdbcconnection pool.
How can I know that my JVM can use the maximum value? Shoot your head? No!
When setting the maximum memory (xmx) value, open a command line and enter the following command:
Check that the JDK version information is displayed normally. You can use this value. Isn't it true that a 32-bit system can use up to 2 GB of memory? That is: 2048 M. We will try it without defense.
Yes? No! Don't say 2048m. Let's make it a little smaller. How about 1700m?
Hey, I can't even connect to M, let alone 2048m. 2048m is just a theoretical value. In this case, I have several machines here, and some machines-xmx1800 are okay, some machines can only reach-xmx1500m.
Therefore, when setting the-XMS and-xmx values, you must first perform this test. Otherwise, your Tomcat will no longer be available in the Tomcat startup command line, if you want to fly, you will not be able to fly, but it will become a pitfall cat.
Ü-xmn
Set the young generation size to 512 MB. Total heap size = size of the young generation + size of the old generation + size of the persistent generation. The permanent generation usually has a fixed size of 64 M. Therefore, increasing the size of the young generation will reduce the size of the old generation. This value has a great impact on the system performance. Sun officially recommends 3/8 of the total heap configuration.
Ü-XSS
Sets the stack size for each thread. This depends on your program to see how much memory a thread will occupy and how many threads may run at the same time. Generally, it is not easy to set the value to more than 1 MB. Otherwise, out ofmemory may easily appear.
Ü-XX: + aggressiveopts
When this parameter is enabled, your JVM will use the latest optimization technology (if any) when the JDK version is upgraded)
U-XX: + usebiasedlocking
Enable an optimized thread lock. We know that on our appserver, each HTTP request is a thread. If some requests are short and some requests are long, requests will be queued, there may even be thread blocking. This optimized thread lock will automatically optimize the thread processing in your appserver.
U-XX: permsize = 128m-xx: maxpermsize = 256 m
JVM uses-XX: permsize to set the non-heap memory initial value. The default value is 1/64 of the physical memory;
When exporting a file with a large amount of data, you must set these two values. Otherwise, a memory overflow error may occur.
Set the maximum non-heap memory size by XX: maxpermsize. The default value is 1/4 of the physical memory.
Therefore, if the physical memory is 4 GB, one of the 64 points is 64 MB, which is the default permsize, that is, the initial memory size of the permanent generation;
1/4 is 1024 MB, which is the default maxpermsize.
Ü-XX: + disableexplicitgc
Explicit calling "system. GC ()" is not allowed in program code ()". We have seen two excellent projects that manually call system at the end of each DAO operation. GC (), I think it seems like this can solve their out ofmemory problem. The price is that the system response time is greatly reduced, just like I'm talking about XMS, the principles explained in xmx are the same. Calling GC in this way leads to a great rise and fall in the JVM of the system and poor performance!
U-XX: + useparnewgc
The adoption of multi-thread parallel recovery for the young generation is fast.
Ü-XX: + useconcmarksweepgc
Cms gc. This feature is only available in later versions. It uses GC estimation trigger and heap occupation trigger.
We know that the frequent and complex GC will cause the JVM to scale up and down, thus affecting the system efficiency. Therefore, when cms gc is used, we can increase the number of GC times, the response time of each GC is very short. For example, after jprofiler is observed after cms gc is used, GC is triggered many times, and each GC takes only a few milliseconds.
Ü-XX: maxtenuringthreshold
Set the maximum age of spam. If it is set to 0, the young generation object directly enters the old generation without going through the VOR area. For applications with many older generations, the efficiency can be improved. If this value is set to a greater value, the young generation object will be copied multiple times in the same vor area, which can increase the survival time of the young generation object, increase the probability that the young generation will be recycled.
The setting of this value is an ideal value obtained based on the Local jprofiler monitoring. It cannot be generalized as original.
Ü-XX: + cmsparallelremarkenabled
Minimize mark time when useparnewgc is used
U-XX: + usecmscompactatfullcollection
When concurrent GC is used, it prevents memoryfragmention and organizes live objects to reduce memory fragments.
U-XX: largepagesizeinbytes
Page size of Java heap
U-XX: + usefastaccessormethods
Get, set method into local code
U-XX: + usecmsinitiatingoccupancyonly
Indicates that the concurrent collector starts collection only after oldgeneration uses the initialization ratio.
U-XX: cmsinitiatingoccupancyfraction = 70
Cmsinitiatingoccupancyfraction(Xmx-xmn) * (100-cmsinitiatingoccupancyfraction)/100> = xmnThe promotion failed will not appear. In my application, xmx is 6000 and xmn is 512, so xmx-xmn is 5488 MB, that is, there are 5488 MB in the old generation, cmsinitiatingoccupancyfraction = 90 indicates that the concurrent garbage collection (CMS) for the old generation starts when the old generation reaches 90%, and 10% of the remaining space is 5488 * 10% = 548 MB, so even if all objects in the xmn (that is, 512 MB in the young generation) are moved to the old generation, the 548 MB space is enough, so as long as the above formula is full, there will be no promotion failed during garbage collection;
Therefore, the settings of this parameter must be associated with xmn.
U-djava. AWT. Headless = true
This parameter is generally used at the end. This full parameter serves this purpose. Sometimes we use some chart tools such as jfreechart in our J2EE project, it is used to output GIF/jpg streams on a web page. In a winodws environment, our app server will not encounter any problems when outputting images, however, in Linux/UNIX environments, an exception is often encountered, which makes your winodws development environment good, but it cannot be displayed in Linux/Unix, therefore, add this parameter to avoid this situation.
The above configuration can basically achieve:
Ü faster system response time
Ü JVM recovery speed increases without affecting the system response rate
Ü JVM memory utilization Maximization
Ü minimize thread congestion
2.3 Tomcat container Optimization
We have optimized the commands during Tomcat startup, there is also an important indicator that increases the JVM usage of the system, the garbage collection efficiency and thread blocking, and the system response efficiency. We have not optimized it, that is, the throughput.
Remember what we said in the third day of study, the system itself can process 1000, and you have not optimized or configured it, so it can only process 25 by default. So let's take a look at the optimization in the Tomcat container.
Open the tomcat installation directory \ conf \ Server. xml file and locate this line:
<Connector Port = "8080" protocol = "HTTP/1.1" |
This line is where the performance parameters of our tomcat container are set. It usually has a default value, which is far from enough for our use, let's take a look at the configuration of the modified section:
<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" /> |
Good freshman Tuo alas ......
It doesn't matter. I will explain it one by one.
Ü uriencoding = "UTF-8"
So that Tomcat can parse the URL of the file containing the Chinese name, which is really convenient. Unlike Apache, there is also a mod_encoding, which needs to be compiled manually
Ü maxsparethreads
Maxsparethreads means that if the number of Idle threads is greater than the set number, these threads are aborted to reduce the total number of threads in the pool.
Ü minsparethreads
The minimum number of standby threads and the number of initialization threads at Tomcat startup.
Ü enablelookups
This function is the same as the hostnamelookups in Apache and is set to disabled.
Ü connectiontimeout
Connectiontimeout is the number of milliseconds for network connection timeout.
Ü maxthreads
Maxthreads Tomcat uses threads to process each request received. This value indicates the maximum number of threads that Tomcat can create, that is, the maximum number of concurrent threads.
Ü acceptcount
Acceptcount indicates that when the number of threads reaches maxthreads, subsequent requests will be placed in a waiting queue. The acceptcount indicates the size of the queue. If the queue is full, refuse connection directly.
Ü maxprocessors and minprocessors
In Java, a thread is the path when the program is running and a code segment that is independent of other control threads in a program. They share the same address space. Multithreading helps programmers write efficient programs with the highest CPU utilization, keeping idle time at the lowest level, and thus accepting more requests.
Generally, there are about 1000 windows instances and about 2000 Linux instances.
Ü useurivalidationhack
Let's take a look at the source code in Tomcat:
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 ); } } |
We can see that if useurivalidationhack is set to "false", it can reduce unnecessary checks on some URLs to reduce overhead.
Ü enablelookups = "false"
To eliminate the impact of DNS queries on performance, we can disable DNS queries by modifying the value of the enablelookups parameter in the server. xml file.
Ü disableuploadtimeout
Similar to keeyalive in Apache
Ü configure the gzip compression (HTTP compression) function 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 website browsing. The principle is that after the client requests a webpage, the server compresses the webpage file and downloads it to the client, the client browser is responsible for decompression and browsing. Compared with ordinary browsing processes such as HTML, CSS, JavaScript, and text, it can save about 40% of the traffic. More importantly, it can also compress pages dynamically generated, including CGI, PHP, JSP, ASP, Servlet, shtml, and other output pages. The compression efficiency is astonishing.
1) compression = "on" enable the compression function
2) compressionminsize = "2048" enables the size of compressed output content. The default value is 2 kb.
3) nocompressionuseragents = "gozilla, Traviata" for the following browsers, compression is not enabled
4) compressablemimetype = "text/html, text/XML" compression type
Finally, do not forget to add the same configuration to port 8443, because if we use the HTTPS protocol, we will use the configuration of port 8443, right?
<! -- Enable Tomcat SSL --> <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 right, All Tomcat optimizations are added. In combination with the performance optimization of Apache in the third day, our architecture can be "Flying". Of course, we will refer to any database optimization steps here, but only rely on these two steps, our system has been greatly improved.
For example, in the previous project, after four rounds of performance testing, the first round was used to locate the problem, and the second round was used to optimize Apache + Tomcat/weblogic, the third round is cluster optimization, and the fourth round is SQL and codes optimization.
How many times has our performance increased by the second round? Let's look at a loaderrunner:
The first column on the left is the stress test report that has not been optimized in the first round.
The column on the right is the stress test report after Apache optimization and tomcat optimization.
How many times has this increased? This is only an improvement without modifying the code. Now I understand how to better tune the code.
How important is Apache and tomcat? If you add the following code, SQL optimization, and database optimization ...... So in my previous project, there was an extreme case where the performance of a single transaction (regardless of throughput or response time) increased by 80 times.
Tomcat optimization 1 (switch)