Tomcat优化
1.1 Tomcat优化概述
利用有限的系统资源能够提高Tomcat的并发处理能力(创建更多的线程处理更多的用户并发请求)
1.2 为什么要了解JVM?
Tomcat是一个Java web容器,依赖于JVM,因此想要对Tomcat的优化,就需要先学习JVM
JVM Java Virsual Machine Java虚拟机
1.3 现代计算机的内存模型
计算机核心硬件组成:CPU、内存、硬盘、GPU、主板
CPU 中央处理单元
- x86复杂指令集
- 减法运算 – 减法aux
- 加法运算 – 加法aux
- 乘法预算 – 乘法aux 2*5
- ARM简易指令集
- 加法运算 – 加法aux
- 减法运算 – 减法aux
- 乘法运算 – 加法aux 2+2+2+2+2
内存模型
1.4 JMM—Java内存模型
1.4.1 JMM介绍
Java内存模型(Java Memory Model),是一种JVM的内存访问控制规范,用于屏蔽JVM对不同硬件环境的访问差异,同时保证JVM内多个线程的数据并发访问的一致性和可见性。
JMM规范
- 屏蔽JVM在和各种不同硬件环境之间的访问差异
- 保证Java程序在各种平台下对内存的访问都能够保证一致性
- 保证多线程并发操作数据的一致性
1.4.2 JMM的原子操作
线程运行过程中对内存的访问步骤
1.4.3 并发编程的三大特性
并发编程的三大特性:原子性、可见性、有序性
-
原子性:一个或多个操作为一个整体,要么全部执行,要不都不执行,并且在执行的过程不会被线程调度机制打断。
-
可见性:当多个线程访问同一个变量时,如果其中的一个线程修改了这个变量的值,其他线程成能够立即看到修改后的值。
- 将多个线程共享的变量使用volatile关键字进行修饰,当某个线程对这个共享变量进行修改操作时,就会触发JMM的嗅探机制(MESI缓存一致性协议)
-
有序性:按照代码的先后顺序进行执行
指令重排
,处理器为了提高代码的执行效率,可能会对输入的代码进行优化,它不保证程序中各个语句的执行先后顺序同输入的代码顺序一致,但是他会保证最终的执行结果和代码顺序执行时的结果一致。int i = 0; //语句1 int j = 0; //语句2 i = i + 10; //语句3 j = i + 5; //语句4 可能执行的顺序是: 1--3--2--4 、 2--1--3--4 不能的执行顺序是: 1--2--4--3
boolean flag = false; Object obj = null; //线程1 obj = getObject(); //-----代码1 flag = true; //-----代码2 flag = obj!=null; //线程2 while(!flag){ Thread.sleep(1000); } obj.method();
-
要想并发程序正确的执行,必须保证原子性、可见性、有序性。
1.5 JVM内存结构
JVM内存结构,指的是Java程序在运行过程中数据在jvm中不同区域的存储
1.6 GC
GC,JVM中负责无用数据回收的垃圾回收期,就是用来释放JVM内存中无用的对象。
1.6.1 什么样的对象是无用对象?
无用对象:没存中没有没引用的对象
- 没有或者不会被使用的对象
- 对象之间有相互引用,但是整体未被引用
1.6.2 GC的回收算法
- 复制算法
- 只能使用内存的1/2
- 标记清除算法
- 会导致内存的碎片化
- 标记整理算法
- 整理过程需要消耗资源
1.6.3 堆区内存结构
Java中的对象主要存储在堆区,Java中的堆区也是也是JVM中最大的一块儿内存。
JVM将堆区分成了2个区域: 新生代和老年代
- 新生代(Young):占堆区内存1/3
- 新生代又分为eden和survivor区
- Eden和Survivor的比例是4:1
- 老年代(Old):占堆区2/3
1.7 Tomcat优化
1.7.1 线程池优化
-
配置线程池 tomcat/conf/server.xml
<!--声明线程池 maxThreads: 最大线程数(Tomcat能够支持的并发上限) minSpareThreads:最小空闲线程 maxIdleTime:超过最小线程数的线程 最大空闲等待时间(单位毫秒) --> <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="230" minSpareThreads="4"/> <!--引用线程池--> <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
1.7.2 JVM内存优化
-
bin/catalina.bat文件 JAVA_OPTS属性进行设置
-
参数说明:
-Xms4096M:堆容量初始值 -Xmx4096M:堆容量最大值 -Xmn1024M:新生代容量,所以老年代容量 = 堆容量 - 新生代容量 = 3072M -Xss256K:线程堆栈空间大小 -XX:MaxDirectMemorySize:Direct Buffer Memory大小 -Djava.awt.headless=true:使用缺少外设的系统配置模式 -Dfile.encoding=UTF-8:设置编码规范 jmx配置用于远程管理 -XX:+HeapDumpOutOfMemoryError:当出现OOM时,打印堆快照 -XX:HeapDumpPath:堆快照打印路径,建议文件后缀设为hprof,可被MAT识别 -XX:+DisableExplicitGC:关闭System.gc() -XX:SurvivorRatio=4: Eden区与Survivor区的大小比值 -XX:+UserConcMarkSweepGC:使用CMS收集器 -XX:+UserParNewGC:新生代使用ParNew收集器 -XX:+CMSParallelRemarkEnabled:降低标记停顿 -XX+UseCMSCompactAtFullCollection:在full gc的时候,对年老代的压缩 -XX:CMSFullGCsBeforeCompaction=0:full gc后不压缩老年代内存空间 -XX:LargePageSizeInBytes:内存页的大小 -XX:+UseFastAccessorMethods:原始类型的快速优化 -XX:+UseCMSInitiatingOccupancyOnly:使用手动定义初始化定义开始CMS收集,禁止hostspot自行触发CMS GC -XX:CMSInitiatingOccupancyFraction=80:老年代使用80%后开始CMS收集 -XX:SoftRefLRUPolicyMSPerMB=0:每兆堆空闲空间中SoftReference的存活时间为0秒
-
调优:是基于对JVM内存使用情况的监控和分析从而对内存的大小和分配比例进行调整。
1.7.3 IO模式优化
- BIO 阻塞IO流(很早期版本)
- NIO NewIO(8.0默认就是NIO)
- APR 从操作系统底层实现IO操作
APR配置
-
Tomcat可以使用APR(ApachePortable Runtime)来提供优越的可伸缩性、性能以及本地服务器技术的更好的继承,让Tomcat的并发性能更加的优秀。
-
下载APR:
http://tomcat.apache.org/download-native.cgi
- tomcat-native-1.2.23-win32-src.zip
- tomcat-native-1.2.23-openssl-1.1.1c-win32-bin.zip
-
将下载的APR包下的tcnative-1.dll拷贝到tomcat的bin目录
-
配置server.xml,修改protocol如下:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" connectionTimeout="20000" redirectPort="8443"/>
-
bin.zip
-
将下载的APR包下的tcnative-1.dll拷贝到tomcat的bin目录
-
配置server.xml,修改protocol如下:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="20000" redirectPort="8443"/>
总结:tomcat优化有三个方面,①线程池优化②JVM优化③IO模式优化