Tomcat性能优化

1)年轻代(Young Gen):年轻代主要存放新创建的对象,内存大小相对会比较小,垃圾回收会比较频繁。年轻代分成1个Eden Space和2个Suvivor Space(命名为A和B)。当对象在堆创建时,将进入年轻代的Eden Space。垃圾回收器进行垃圾回收时,扫描Eden Space和A Suvivor Space,如果对象仍然存活,则复制到B Suvivor Space,如果B Suvivor Space已经满,则复制到Old Gen。同时,在扫描Suvivor Space时,如果对象已经经过了几次的扫描仍然存活,JVM认为其为一个持久化对象,则将其移到Old Gen。扫描完毕后,JVM将Eden Space和A Suvivor Space清空,然后交换A和B的角色(即下次垃圾回收时会扫描Eden Space和B Suvivor Space。这么做主要是为了减少内存碎片的产生。
我们可以看到:Young Gen垃圾回收时,采用将存活对象复制到到空的Suvivor Space的方式来确保尽量不存在内存碎片,采用空间换时间的方式来加速内存中不再被持有的对象尽快能够得到回收。

2)年老代(Tenured Gen):年老代主要存放JVM认为生命周期比较长的对象(经过几次的Young Gen的垃圾回收后仍然存在),内存大小相对会比较大,垃圾回收也相对没有那么频繁(譬如可能几个小时一次)。年老代主要采用压缩的方式来避免内存碎片(将存活对象移动到内存片的一边,也就是内存整理)。当然,有些垃圾回收器(譬如CMS垃圾回收器)出于效率的原因,可能会不进行压缩。

3)持久代(Perm Gen):持久代主要存放类定义、字节码和常量等很少会变更的信息。

JVM垃圾收集算法
1 引用计数算法

2 根搜索算法

JVM垃圾回收算法
1 复制算法

2 标记清除算法

3 标记整理压缩算法

JVM内存回收
1 串行回收
gc单线程内存回收,会暂停所有用户线程

2 并行回收
多个gc线程并行工作,但此时用户线程是暂停的,所以serial是串行的,Paralle收集器是并行的,而CMS收集器是并发的

3 并发回收
用户线程与GC线程同时执行(不一定是并行,可能交替,但总体上是在同时执行的),不需要停顿用户线程(其实在CMS中用户线程还是需要停顿的,只是非常短,GC线程在另一个CPU上执行)

GC 收集器的选择
JVM中有大致5类收集器:串行收集器,并行收集器,并行压缩收集器,CMS 收集器,G1收集器。其中并行被并行压缩收集器所替代,CMS 收集器被G1收集器所替代,所以可供选择的只剩下三种。

(1)串行收集器(Serial Collector)
在同一时间只会执行一件垃圾清理任务,非常适用于单线程,单CPU 架构的程序,串行收集器的开销也比较小,在老年代中使用mark-sweep-compact(标记—扫描-压缩)算法, 对于堆内存不是很大的程序比较适用。
串行收集器适用场景:客户端程序(-client)和单线程比较小的应用。可以声明-XX:+UseSerialGC 选项使用串行收集器。

(2)并行压缩收集器(Parallel Compacting Collector)
并行压缩收集器是在J2SE1.5后引入,与并行收集器(并行收集器又被称作吞吐量收集器)最大的不同是对老年代的回收使用了不同的算法,并行压缩收集器最终会取代并行收集器。并行压缩收集器最大的优点就是在消耗部分硬件性能及多CPU 支持下可以做到更短的stop-the-world 暂停,使回收效率更高从而增加了程序的吞吐量。
并行压缩收集器适用场景:程序稳定长期运行,希望任何时候我们的程序都能得到响应,即使程序执行速度缓慢,例如一些后台程序。硬件水平较高,例如多CPU,多物理内存的服务器可以选择并行压缩收集器。可以声明-XX:+UseParallelOldGC 选项使用并行压缩收集器。

(3)CMS 收集器(Concurrent Mark-Sweep (CMS) Collector)
在很多应用中,更加注重快速的相应时间而不是吞吐量。新生代的垃圾回收通常不会造成长时间的应用程序中断,但是,对于老年代,特别是当Heap 已使用量比较大的时候会导致长时间的程序中断(虽然这种情况不常发生).JVM 引入CMS 的目的就是为了解决这个问题。
CMS 收集器适用场景(G1同理):对于老年代使用率比较高的应用程序适合CMS 收集器,对停顿时间有较严格要求的程序也比较适合使用CMS 收集器。所以CMS 收集器多用于应用服务器程序上,例如web系统等。这类系统的共同特点就是响应时间一般较短,否则容易造成用户体验差的评价。可以声明-xx:+UseConcMarkSweepGC 选项使用CMS。如果你还想让CMS 运行与增量模式下,则可声明–XX:+CMSIncrementalMode 选项启用增量模式。增量模式指的是把收集器的工作分成多个时间块,然后在两次新生代的回收期间加以运行,这种方式可以更进一步减少暂停的时间。

设置初始堆大小 年轻代大小
JVM参数优化
一般建议设置
-Xms = Xmx
XX:NewSize = XX:MaxNewSize
XX:PermSize = XX:MaxPermSize (这个参数8之后废弃掉了,会有警告信息)
好处是避免每次在gc后,调整堆大小,较少系统内存分配开销
整个堆大小 = 年轻代大小 + 年老代大小 + 持久代大小

vim /usr/local/tomcat/bin/catalina.sh
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms2048m -Xmx2048m -XX:NewSize=512m -XX:MaxNewSize=512m"
生产配置
JAVA_OPTS="-Xms3776m -Xmx3776m -Xmn1228m -XX:PermSize=512m -XX:MaxPermSize=512m -Xss512K -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8 -XX:SurvivorRatio=6 -XX:+DisableExplicitGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=75 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC"

选择适合的垃圾回收器
优化的终极目标是减少 fullgc的频率

-Xss512K设置每个线程的堆栈大小
-XX:SurvivorRatio=6:设置年轻代中Eden区与Survivor区的大小比值.设置为6,则两个Survivor区与一个Eden区的比值为2:6,一个Survivor区占整个年轻代的1/8
-XX:+DisableExplicitGC禁止System.gc():免得程序员误调用gc方法影响性能
-XX:+UseParNewGC:设置年轻代为并行收集
-XX:+UseConcMarkSweepGC:设置年老代为并发收集
-XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩.可能会影响性能,但是可以消除碎片
-XX:CMSFullGCsBeforeCompaction=0:多少次Full GC后,对年老代进行压缩
-XX:+CMSParallelRemarkEnabled, 为了减少第二次暂停的时间,开启并行remark,降低标记停顿
-XX:+CMSClassUnloadingEnabled垃圾回收会清理持久代,移除不再使用的classes。这个参数只有在 UseConcMarkSweepGC 也启用的情况下才有用。
-XX:CMSInitiatingOccupancyFraction=75,老年代垃圾占比达到这个阈值开始CMS收集,1.6默认是92。设置过高容易导致并发收集失败,会出现SerialOld收集的情况。
-XX:SoftRefLRUPolicyMSPerMB=0 每兆堆空闲空间的 soft reference 保持存活的毫秒数 因为 soft reference 只会在垃圾回收时才会被清除,而垃圾回收并不总在发生。系统默认为一秒,觉得没必要等1秒,客户集中不用就立刻清除

tomcat参数优化
maxThreads=”xxx” 最大线程数
minSpareThreads=”xxx” 初始化时创建的线程数
maxSpareThreads=”xxx” 最大空闲 一旦创建的线程数超过这个值tomcat就会关闭不再需要的socket线程
acceptCount=”xxx” 指定当所有可以使用的处理请求的线程都被使用时,可以放到处理队列中的请求数,超过这个数请求将不予处理
maxConnections=“xxx” 当当前socket连接超过maxConnections的时候,acceptor线程自己会阻塞等待,等连接降下去之后,才去处accept队列的下一个连接
注:maxThreads、minSpareThreads是tomcat工作线程池的配置参数
acceptCount、maxConnections是tcp层相关的参数

prestartminSpareThreads,在 Tomcat 初始化的时候就初始化 minSpareThreads 的参数值,如果不等于 true,minSpareThreads 的值就没啥效果了
acceptorThreadCount,用于接收连接的线程的数量,默认值是1。一般这个指需要改动的时候是因为该服务器是一个多核CPU,如果是多核 CPU 一般配置为 2
maxPostSize,以 FORM URL 参数方式的 POST 提交方式,限制提交最大的大小,默认是 2097152(2兆),它使用的单位是字节。10485760 为 10M。如果要禁用限制,则可以设置为 -1

关闭DNS查寻 enableLookups false
关闭不必要检查 userURIValidationHack=”false”
开启压缩 compression=“on”
可压缩数据大小compressionMinSize=“1024”
哪些浏览器不压缩 noCompressionUserAgents=“gozilla,traviata”
压缩类型 compressableMimeType=“text/css text/javascript application/json application/javascript application/x-javascript application/xml”
允许Servlet容器,正在执行使用一个较长的连接超时值 disableUploadTimeOut

<Connector server="www.aaa.com" port="8080" 
               protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="300" 
               minSpareThreads="30" 
               maxSpareThreads="80"
               prestartminSpareThreads="true"
               acceptorThreadCount="2"
               acceptCount="80000" 
               maxConnections="819200" 
               executor="tomcatThreadPool"
               connectionTimeout="20000" 
               keepAliveTimeout="15000" 
               enableLookups="false"
               disableUploadTimeout="true"
               maxPostSize="10485760"
               userURIValidationHack="false" compression="on" compressionMinSize="1024"
               noCompressionUserAgents="MSIE[1-6]\.(?!.*SV1)"
               compressableMimeType="text/css text/javascript application/json application/javascript  application/x-javascript application/xml"
               redirectPort="8443" />

Tomcat IO模型
bio
bio(blocking I/O,阻塞式I/O操作),表示Tomcat使用的是传统的Java I/O操作(即java.io包及其子包)。
老版本默认的模式,性能最差,没有经过任何优化处理和支持。

nio (tomcat8 默认就是nio模型 我没有每个版本都测试 有兴趣的朋友可以看看各个版本使用的模型)
nio(non-blocking I/O),Java SE 1.4及后续版本提供的一种新的I/O操作方式(即java.nio包及其子包)。Java nio是一个基于缓冲区、并能提供非阻塞I/O操作的Java API。拥有比传统I/O操作(bio)更好的并发运行性能。 要让Tomcat以nio模式来运行,修改配置文件:tomcat/conf/server.xml
改为 protocol=“org.apache.coyote.http11.Http11NioProtocol”

apr
apr(Apache Portable Runtime/Apache可移植运行时库),Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高Tomcat对静态文件的处理性能。从操作系统级别来解决异步的IO问题,大幅度的提高性能。 Tomcat apr也是在Tomcat上运行高并发应用的首选模式。也是Tomcat生产环境运行的首选方式
要让Tomcat以apr模式来运行,必须安装apr和native

查看Tomcat 运行模式
http://192.168.56.7:8080/manager/status
在这里插入图片描述
apr模式
需要提前安装所需要的依赖,首先是需要安装openssl和apr
需要openssl版本大于等于1.0.2 而目前系统版本是1.0.1e,所以需要更新版本

所需包打包下载地址:https://download.csdn.net/download/bjgaocp/11484660 里面Tomcat里面的配置文件已经优化修改完毕

tar -xvf apr-1.6.2.tar.gz
cd apr-1.6.2
sed -i ‘s/ R M &quot; RM &quot; RM"cfgfile"/# R M &quot; RM &quot; RM"cfgfile"/g’ configure
./configure --prefix=/usr/local/apr
show
make && make install

tar -zxvf apr-iconv-1.2.1.tar.gz
cd apr-iconv-1.2.1
./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr
make && make install

tar -zxvf apr-util-1.6.0.tar.gz
cd apr-util-1.6.0
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apr-iconv/bin/apriconv
make && make install

tar -zxvf openssl-1.0.2k.tar.gz
cd openssl-1.0.2k
./config shared zlib
make && make install

mv /usr/bin/openssl /usr/bin/openssl.old
mv /usr/include/openssl /usr/include/openssl.old
ln -sf /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -sf /usr/local/ssl/include/openssl/ /usr/include/openssl

echo “/usr/local/ssl/lib” >> /etc/ld.so.conf
echo “/usr/local/apr/lib” >> /etc/ld.so.conf
ldconfig

ln -s /usr/local/ssl/lib/* /usr/lib/

tar -xvf tomcat-native.tar.gz
cd tomcat-native-1.2.16-src/native
./configure --with-apr=/usr/local/apr --with-java-home=/usr/local/jdk1.7.0_79/ --with-ssl=/usr/local/ssl/
make && make install

然后进入tomcat安装目录,编辑配置文件:conf/server.xml
将默认的protocol="HTTP/1.1"修改为protocol=“org.apache.coyote.http11.Http11AprProtocol”

修改完成保存并退出,然后有以下两种方法来引入apr:
方法1:推荐方法 上面使用的就是此种方法
echo “/usr/local/apr/lib” >> /etc/ld.so.conf
ldconfig

方法2:配置tomcat安装目录下:bin/catalina.sh文件引入apr
添加一行新的就可以:JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/apr/lib"

方法3:在环境变量中加入apr的目录,让tomcat可以使用系统变量搜索到,编辑/etc/profile在最后添加如下两行内容

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
export LD_RUN_PATH=$LD_RUN_PATH:/usr/local/apr/lib

source /etc/profile

配置完成之后,重启一下tomcat,然后查看日志logs/catalina.out可以看到http已经以apr模式启动了
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值