Tomcat 并发调优

一. Linux系统配置

1. 增大最大打开文件数限制

 $ sudo vim /etc/sysctl.conf 
 # add "fs.file-max = 8061540"
 $ sudo vim /etc/security/limit.conf 
 # add "* soft nofile 8192"  and "* hard nofile 16384"

2. 优化网络

$ sudo vim /etc/sysctl.conf

优化后的内容如下:

 net.ipv4.ip_forward = 0

 # Controls source route verification
 net.ipv4.conf.default.rp_filter = 1

 # Do not accept source routing
 net.ipv4.conf.default.accept_source_route = 0

 # Controls the System Request debugging functionality of the kernel
 kernel.sysrq = 0

 # Controls whether core dumps will append the PID to the core filename
 # Useful for debugging multi-threaded applications
 kernel.core_uses_pid = 1

 # Controls the use of TCP syncookies
 net.ipv4.tcp_syncookies = 1

 # Controls the maximum size of a message, in bytes
 kernel.msgmnb = 65536

 # Controls the default maxmimum size of a mesage queue
 kernel.msgmax = 65536

 # Controls the maximum shared segment size, in bytes
 kernel.shmmax = 68719476736

 # Controls the maximum number of shared memory segments, in pages
 kernel.shmall = 4294967296
 vm.swappiness = 0
 kernel.core_pattern = /tmp/corefile/core-%e-%p-%t
 net.ipv4.tcp_tw_reuse = 1
 net.ipv4.tcp_tw_recycle = 1
 net.ipv4.tcp_fin_timeout = 5
 net.ipv4.tcp_max_syn_backlog = 65536
 net.core.netdev_max_backlog =  32768
 net.core.somaxconn = 32768
 net.core.wmem_default = 8388608
 net.core.rmem_default = 8388608
 net.core.rmem_max = 16777216
 net.core.wmem_max = 16777216
 net.ipv4.tcp_timestamps = 0
 net.ipv4.tcp_synack_retries = 2
 net.ipv4.tcp_syn_retries = 2
 net.ipv4.tcp_mem = 94500000 915000000 927000000
 net.ipv4.tcp_max_orphans = 3276800
 net.ipv4.ip_local_port_range = 2000  65535
 net.ipv4.tcp_max_tw_buckets = 5000
 net.ipv4.netfilter.ip_conntrack_max = 1000000

二. Tomcat内存优化

Tomcat内存优化主要是对 Tomcat 启动参数优化,我们可以在 Tomcat 的启动脚本 catalina.sh 中设置 JAVA_OPTS 参数

-server:  启用jdk的server版,一定要作为第一个参数,在多个CPU时性能佳 
-Xms: 初始Heap大小,使用的最小内存,cpu性能高时此值应设的大一些 
-Xmx: java heap最大值,使用的最大内存 
上面两个值是分配JVM的最小和最大内存,取决于硬件物理内存的大小,建议均设为物理内存的一半。 
-XX:PermSize:设定内存的永久保存区域 
-XX:MaxPermSize:设定最大内存的永久保存区域 
-XX:MaxNewSize: 
-Xss 15120 这使得JBoss每增加一个线程(thread)就会立即消耗15M内存,而最佳值应该是128K,默认值好像是512k. 
+XX:AggressiveHeap 会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。 
-Xss:每个线程的Stack大小 
-verbose:gc 现实垃圾收集信息 
-Xloggc:gc.log 指定垃圾收集日志文件 
-Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一 
-XX:+UseParNewGC :缩短minor收集的时间 
-XX:+UseConcMarkSweepGC :缩短major收集的时间 
提示:此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适。

三. Tomcat并发优化

1.Tomcat连接相关参数

在Tomcat配置文件conf/server.xml 中的Connector配置中

 acceptCount:允许的最大连接数
 enableLookups:是否反查域名,取值为: true 或 false 。为了提高处理能力,应设置为 false
 connectionTimeout:网络连接超时,单位:毫秒。设置为 0 表示永不超时,这样设置有隐患的。通常可设置为 30000 毫秒。
 其中和最大连接数相关的参数为maxProcessors 和 acceptCount。如果要加大并发连接数,应同时加大这两个参数。

2.调整连接器connector的并发处理能力

  maxThreads        客户请求最大线程数
  minSpareThreads   Tomcat初始化时创建的 socket 线程数
  maxSpareThreads   Tomcat连接器的最大空闲 socket 线程数
  enableLookups     若设为true, 则支持域名解析,可把 ip 地址解析为主机名
  redirectPort      在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口
  acceptAccount     监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads)
  connectionTimeout 连接超时
  URIEncoding    URL统一编码

3.Tomcat缓存优化

      compression 打开压缩功能   
      compressionMinSize   启用压缩的输出内容大小,这里面默认为2KB
      compressableMimeType 压缩类型
      connectionTimeout 定义建立客户连接超时的时间. 如果为 -1, 表示不限制建立客户连接的时间

结合以上方面,对server.xml的现有配置为:

      <Connector  port="9027" 

              maxHttpHeaderSize="8192"

              maxThreads="2048"

              minSpareThreads="256"

              enableLookups="false"

              compression="on"

              compressionMinSize="2048"

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

              connectionTimeout="20000"

              URIEncoding="utf-8"

              acceptCount="2048"

              redirectPort="8443"

              disableUploadTimeout="true"

              executor="tomcatThreadPool" />

      <Executor name="tomcatThreadPool" 
                namePrefix="catalina-exec-" 
                maxThreads="2048" 
                minSpareThreads="512" 
                prestartminSpareThreads="true" />

四. Tomcat Native

Tomcat可以使用APR来提供超强的可伸缩性和性能,更好地集成本地服务器技术。APR(Apache Portable Runtime)
是一个高可移植库,它是Apache HTTP Server 2.x的核心。APR有很多用途,包括访问高级IO功能(例如sendfile,
epoll和OpenSSL),OS级别功能(随机数生成,系统状态等等),本地进程管理(共享内存,NT管道和UNIX sockets)。这些功能可以
使Tomcat作为一个通常的前台WEB服务器,能更好地和其它本地web技术集成,总体上让Java更有效率作为一个高性能web服务器
平台而不是简单作为后台容器

在产品环境中,特别是直接使用Tomcat做WEB服务器的时候,应该使用Tomcat Native来提高其性能。
说白了,就是如何 在Tomcat中使用JNI的方式来读取文件以及进行网络传输。这个东西可以大大提升Tomcat对静态文件的处理性能,同时如果你使用了HTTPS方式 传输的话,也可以提升SSL的处理性能。

  • a. 安装 apr
     $ sudo ./configure --prefix=/opt/apr
     $ sudo make
     $ sudo make install
  • b. 安装 apr-iconv
     $ sudo ./configure --prefix=/opt/apr-iconv --with-apr=/opt/apr 
     $ sudo make
     $ sudo make install
  • c. 安装 apr-util
     $ sudo  ./configure --prefix=/opt/apr-util  --with-apr=/opt/apr --with-apr-iconv=/opt/apr-iconv/bin/apriconv 
     $ sudo make
     $ sudo make install
  • d. 安装 tomcat-native
     $ cd $TOMCAT_HOME/bin/tomcat-native-1.1.30-src/jni/native
     $ ./configure --with-apr=/opt/apr --with-java-home=/usr/lib/jvm/java-7-openjdk-i386/ 
     $ sudo make
     $ sudo make install

五. 总结

为了提高Tomcat的并发处理能力,我从以上几个方面进行了逐步的增量调优,每次优化或者做出改变之后,都从Client用ab模拟并发,观察QPS等指标,并同时在Server端监控各种系统信息:

           sudo /opt/apache/bin/ab -n 50000 -c 2000 http://192.168.1.2:9027/performance/test.jsp 

目前比较好的测试结果如下:

           Server Software:        Apache-Coyote/1.1
           Server Hostname:        192.168.1.2
           Server Port:            9027

           Document Path:          /performance/test.jsp
           Document Length:        253 bytes

           Concurrency Level:      2000
           Time taken for tests:   4.089 seconds
           Complete requests:      50000
           Failed requests:        0
           Total transferred:      25100000 bytes
           HTML transferred:       12650000 bytes
           Requests per second:    12227.55 [#/sec] (mean)
           Time per request:       163.565 [ms] (mean)
           Time per request:       0.082 [ms] (mean, across all concurrent requests)
           Transfer rate:          5994.36 [Kbytes/sec] received

           Connection Times (ms)
                         min  mean[+/-sd] median   max
           Connect:        9   77 138.5     54    1070
           Processing:    15   81  51.7     76     617
           Waiting:       11   59  34.4     57     608
           Total:         40  158 148.6    127    1221

           Percentage of the requests served within a certain time (ms)
             50%    127
             66%    147
             75%    177
             80%    180
             90%    196
             95%    219
             98%    662
             99%   1105
            100%   1221 (longest request)

但在调优时发现,无论怎样提高各种参数的阈值,并发性都不会再得到明显的提高,有时反而会降低。而且在设置JAVA_OPTS时,-Xms, -Xmx超过2048m时,就会提示超过内存限制。在网路上看到以下内容可以解释这个问题:

`JVM`内存限制于实际的最大物理内存,假设物理内存无限大的话,`JVM`内存的最大值跟操作系统有很大的关系。
简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般
来说`Windows`系统下为1.5G-2G,`Linux`系统下为2G-3G),而64bit以上的处理器就不会有限制了。
Tags// , ,
More Reading
Older// NLPNote