优秀的编程知识分享平台

网站首页 > 技术文章 正文

让你眼前一亮的3. Tomcat 性能调优 (值得收藏)

nanyue 2024-10-21 06:14:16 技术文章 2 ℃

目录

  • 3. Tomcat 性能调优3.1 Tomcat 性能测试3.2 Tomcat 性能优化3.2.1Tomcat配置调优1.禁用AJP连接2.Connector 连接器的选择3.Executor线程池调整3.2.2 JVM参数调优1) JVM内存参数2) GC策略3.2.3 Tomcat架构调优动静分离:Tomcat集群:修改Tomcat默认端口号tomcat中部署项目的方式

3. Tomcat 性能调优

性能优化的三个指标

降低响应时间 :   

提高系统吞吐量(QPS) :  QPS (每秒请求量)     T(事务) PS (每秒处理事务的数量) 

提高服务的可用性:    

性能优化的原则

具体情况具体分析
积少成多

性能分析工具

JConsole  jvm性能监控平台:  主要监控 内存和CPU的情况

JMeter 分布式性能测试工具:   响应时间、吞吐量、错误率

性能优化测试指标

正确率、CPU占有率、QPS、JVM

3.1 Tomcat 性能测试

我们使用JMeter来进行测试:

3.2 Tomcat 性能优化

3.2.1Tomcat配置调优

1.禁用AJP连接

默认状态下,Tomcat会启动AJP服务,占用8009端口。

AJP是什么?有什么作用呢?

AJP(Apache JServer Protocol) 是为Tomcat与HTTP服务器之间通信而定制的协议,能提供较高的通信速度和效率。

Tomcat虽然是一个javaWeb服务器,可以对静态资源进行解析,但它最主要的作用是提供Servlet 和 Jsp容器,对静态资源的解析肯定不如一些专业的Http服务器 如:apache、nginx 。所以通常生产环境会把Tomcat和其他http服务器搭配使用, 所有请求都访问http服务器,如果访问的资源是Servlet或Jsp则http服务器将请求交由Tomcat处理,如果静态资源 http服务器直接处理, ajp就是apache服务器和tomcat服务器通信的主要协议,nginx 和 浏览器是不支持这个协议的,所以如果你不使用Tomcat和Apache服务器整合的话,这个AJP协议服务是没必要开启的。

ajp就是下面这行代码来配置,主要注释它就可以禁用AJP

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

2.Connector 连接器的选择

Tomcat 连接器的三种方式: bio、nio 和 apr,三种方式性能差别很大,apr 的性能最优, bio 的性能最差。而 Tomcat 7 使用的 Connector 默认就启用的 Apr 协议,但需要系统安装 Apr 库,否则就会使用 bio 方式。

BIO:

一个线程处理一个请求。缺点:并发量高时,线程数较多,浪费资源。

Tomcat7或以下,在Linux系统中默认使用这种方式。

NIO:

利用Java的异步IO处理,可以通过少量的线程处理大量的请求。

Tomcat8在Linux系统中默认使用这种方式。

Tomcat7必须修改Connector配置来启动:

APR:

即Apache Portable Runtime,从操作系统层面解决io阻塞问题。

Tomcat7或Tomcat8在Win7或以上的系统中启动默认使用这种方式。

Linux如果安装了apr和native,Tomcat直接启动就支持apr。

tomcat8 提供了nio2,效率要比nio快些,所以如果是tomcat8之前的版本推荐使用nio ,如果是tomcat8及之后的版本使用nio2

APR( Apache Portable Runtime) 提供卓越的伸缩性,更强的性能以及跟原生服务器技术更好的集成。

如果使用APR要保证1.配置文件中引入了APR的监听 2.服务器上安装APR的相关软件

linux配置APR:

安装依赖

yum install apr-devel yum install openssl-devel yum install gcc yum install make

安装APR包

进入 apache-tomcat-8.5.39/bin 执行命令 tar -xzvf tomcat-native.tar.gz

输入命令 cd tomcat-native-1.2.21-src/native/

进入到native文件夹下

执行命令 ./configure && make && make install

安装后会出现这个界面,表示安装成功,并给出了安装后的目录位置

通过上图我们可以看到 我们还需要配置两个环境变量

输入命令使环境变量生效 source /etc/profile

修改server.xml 配置


启动tomcat查看日志

进入到 /logs目录 执行命令 tail -f -n 200 catalina.out

<Connector  executor="tomcatThreadPool"
            port="8080"
            protocol="org.apache.coyote.http11.Http11Nio2Protocol"
            connectionTimeout="20000"
		    redirectPort="8443"/>

Connector参数解释

URIEncoding:指定 Tomcat 容器的 URL 编码格式,语言编码格式这块倒不如其它 WEB 服务器软件配置方便,需要分别指定。

面试可以说:设置连接超时时间,当后台出现问题,连接可以及时断掉

connnectionTimeout: 网络连接超时,单位:毫秒,设置为 0 表示永不超时,这样设置有隐患的。通常可设置为 30000 毫秒(30秒),可根据检测实际情况,适当修改。

enableLookups: 是否反查域名,以返回远程主机的主机名,取值为:true 或 false,如果设置为false,则直接返回IP地址,为了提高处理能力,应设置为 false。
disableUploadTimeout:上传时是否使用超时机制。
connectionUploadTimeout:上传超时时间,毕竟文件上传可能需要消耗更多的时间,这个根据你自己的业务需要自己调,以使Servlet有较长的时间来完成它的执行,需要与上一个参数一起配合使用才会生效。
acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求的最大队列长度,超过这个数的请求将不予处理,默认为100个。
keepAliveTimeout:长连接最大保持时间(毫秒),表示在下次请求过来之前,Tomcat 保持该连接多久,默认是使用 connectionTimeout 时间,-1 为不限制超时。
maxKeepAliveRequests:表示在服务器关闭之前,该连接最大支持的请求数。超过该请求数的连接也将被关闭,1表示禁用,-1表示不限制个数,默认100个,一般设置在100~200之间。

面试可以说压缩:连接器参数开启响应数据压缩

compression:是否对响应的数据进行 GZIP 压缩,off:表示禁止压缩;on:表示允许压缩(文本将被压缩)、force:表示所有情况下都进行压缩,默认值为off,压缩数据后可以有效的减少页面的大小,一般可以减小1/3左右,节省带宽。

compressionMinSize:表示压缩响应的最小值,只有当响应报文大小大于这个值的时候才会对报文进行压缩,如果开启了压缩功能,默认值就是2048KB。

compressableMimeType:压缩类型,指定对哪些类型的文件进行数据压缩。
noCompressionUserAgents="gozilla, traviata": 对于以下的浏览器,不启用压缩。

参考配置

连接器的具体参考配置: 
<Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               URIEncoding="UTF-8"
               connectionTimeout="30000"
               enableLookups="false"
               disableUploadTimeout="false"
               connectionUploadTimeout="150000"
               acceptCount="300"
               keepAliveTimeout="120000"
               maxKeepAliveRequests="1"
               compression="on"
               compressionMinSize="2048"         compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png" redirectPort="8443" />

3.Executor线程池调整

默认配置下,Tomcat 会为每个连接器创建一个绑定的线程池(最大线程数 200),服务启动时,默认创建了 5 个空闲线程随时等待用户请求

默认情况:

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>

修改连接池:

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="500" minSpareThreads="100" maxSpareThreads="50" maxIdleTime="60000"/>

机器比较好情况:最小线程数不超过<100,最大线程数不超过<500

然后,修改<Connector …>节点,增加 executor 属性,调整为

<Connector  executor="tomcatThreadPool"
            port="8080"
            protocol="org.apache.coyote.http11.Http11Nio2Protocol"
            connectionTimeout="20000"
		    redirectPort="8443"/>

Executor参数解释:

maxThreads,最大并发数,默认设置 200,一般建议在 500 ~ 800,根据硬件设施和业务来判断
minSpareThreads,Tomcat 初始化时创建的线程数,默认设置 25
prestartminSpareThreads,在 Tomcat 初始化的时候就初始化 minSpareThreads 的参数值,如果不等于 true,minSpareThreads 的值就没啥效果了
maxQueueSize,最大的等待队列数,超过则拒绝请求

3.2.2 JVM参数调优

Tomcat是一款Java应用,那么JVM的配置便与其运行性能密切相关,而JVM优化的重点则集中在内存分配和GC策略的调整上,因为内存会直接影响服务的运行效率和吞吐量,JVM垃圾回收机制则会不同程度地导致程序运行中断。可以根据应用程序的特点,选择不同的垃圾回收策略,调整JVM垃圾回收策略,可以极大减少垃圾回收次数,提升垃圾回收效率,改善程序运行性能。

1) JVM内存参数

参数

参数作用

优化建议

-server

启动Server,以服务端模式运行

服务端模式建议开启

-Xms

最小堆内存

建议与-Xmx设置相同

-Xmx

最大堆内存

建议设置为可用内存的80%

-XX:MetaspaceSize

元空间初始值


-XX:MaxMetaspaceSize

元空间最大内存

默认无限

-XX:NewSize

新生代初始值


-XX:MaxNewSize

新生代最大内存

默认16M

-XX:NewRatio

年轻代和老年代大小比值,取值为整数,默认为2

不建议修改

-XX:SurvivorRatio

Eden区与Survivor幸存者区大小的比值,取值为整数,默认为8

不建议修改

-Xms:Java虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能;

可以利用JDK自带的工具进行验证,这些工具都在/bin目录下:
1)jps:用来显示本地的java进程,以及进程号,进程启动的路径等。
2)jmap:观察运行中的JVM 物理内存的占用情况,包括Heap size , Perm size等。
进入命令行模式后,进入JAVA_HOME/bin目录下,然后输入jps命令:
free -m 命令查看当前服务器的可用内存

JAVA_OPTS="-server -Xms2048m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m  -XX:SurvivorRatio=8"

2) GC策略

JVM垃圾回收性能有以下两个主要的指标:

  • 吞吐量:工作时间(排除GC时间)占总时间的百分比, 工作时间并不仅是程序运行的时间,还包含内存分配时间。
  • 暂停时间:测试时间段内,由垃圾回收导致的应用程序停止响应次数/时间。

不同的应用程序, 对于垃圾回收会有不同的需求。 JVM 会根据运行的平台、服务器资源配置情况选择合适的垃圾收集器、堆内存大小及运行时编译器。如无法满足需求, 参考以下准则:

A. 程序数据量较小,选择串行收集器。

B. 应用运行在单核处理器上且没有暂停时间要求, 可交由JVM自行选择或选择串行收集器。

C. 如果考虑应用程序的峰值性能, 没有暂停时间要求, 可以选择并行收集器。

D. 如果应用程序的响应时间比整体吞吐量更重要, 可以选择并发收集器。

查看Tomcat中的默认的垃圾收集器:

1). 在tomcat/bin/catalina.sh的配置中, 加入如下配置

JAVA_OPTS=" -Djava.rmi.server.hostname=192.168.18.129 -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.rmi.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

2). 打开 jconsole , 查看远程的tomcat的概要信息

连接远程tomcat

GC参数:

参数

描述

-XX:+UseSerialGC

启用串行收集器

-XX:+UseParallelGC

启用并行垃圾收集器,配置了该选项,那么 -XX:+UseParallelOldGC默认启用

-XX:+UseParallelOldGC

FullGC 采用并行收集,默认禁用。如果设置了 -XX:+UseParallelGC则自动启用

-XX:+UseParNewGC

年轻代采用并行收集器,如果设置了 -XX:+UseConcMarkSweepGC选项,自动启用

-XX:+ParallelGCThreads

年轻代及老年代垃圾回收使用的线程数。默认值依赖于JVM使用的CPU个数

-XX:+UseConcMarkSweepGC

并发垃圾收集器 对于老年代,启用CMS垃圾收集器。 当并行收集器无法满足应用的延迟需求是,推荐使用CMS或G1收集器。
启用该选项后, -XX:+UseParNewGC 自动启用。

-XX:+UseG1GC

启用G1收集器。 G1是服务器类型的收集器, 用于多核、大内存的机器。它在保持高吞吐量的情况下,高概率满足GC暂停时间的目标。

我们也可以在测试的时候,将JVM参数调整之后,将GC的信息打印出来,便于为我们进行参数调整提供依据,具体参数如下:

选项

描述

-XX:+PrintGC

打印每次GC的信息

-XX:+PrintGCApplicationConcurrentTime

打印最后一次暂停之后所经过的时间, 即响应并发执行的时间

-XX:+PrintGCApplicationStoppedTime

打印GC时应用暂停时间

-XX:+PrintGCDateStamps

打印每次GC的日期戳

-XX:+PrintGCDetails

打印每次GC的详细信息

-XX:+PrintGCTaskTimeStamps

打印每个GC工作线程任务的时间戳

-XX:+PrintGCTimeStamps

打印每次GC的时间戳

在bin/catalina.sh的脚本中 , 追加如下配置 :

JAVA_OPTS="-XX:+UseConcMarkSweepGC  -XX:+PrintGCDetails"
64位系统 centos 6.4 内存8G服务器 
-server 
-Xms6000M  
-Xmx6000M   
-Xmn500M    
-XX:MetaspaceSize=500M    
-XX:MaxMetaspaceSize=500M 
-XX:SurvivorRatio=65536  
-XX:MaxTenuringThreshold=0
-Xnoclassgc
-XX:+DisableExplicitGC
-XX:+UseParNewGC    
-XX:+UseConcMarkSweepGC    
-XX:+UseCMSCompactAtFullCollection   
-XX:CMSFullGCsBeforeCompaction=0 
-XX:CMSInitiatingOccupancyFraction=80       
-XX:+PrintClassHistogram  
-XX:+PrintGCDetails  
-XX:+PrintGCTimeStamps  
-XX:+PrintHeapAtGC   
-Xloggc:log/gc.log

3.2.3 Tomcat架构调优

前面我们已经通过系统、jvm、和tomcat自身大大提升的tomcat的性能,但tomcat的性能是有极限的,Tomcat理论支持500左右并发,所以接下来我们会聊聊在如何合理使用tomcat上,实际上也就是架构的 层面聊聊如果优化。这里面我们主要讨论两个优化思路:动静分离Tomcat集群

就需要搭建Tomcat的集群,而目前比较流程的做法就是通过Nginx来实现Tomcat集群的负载均衡。

动静分离:

Tomcat主要处理servlet、jsp占优势,项目中静态资源(图片、视频、.CSS、.html、.js)访问,耗费请求连接,把静态资源放在Nginx服务器中,静态请求不经过Tomcat,不占并发数。
Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现。

优点:
1、可以高并发连接
官方测试Nginx能够支撑5万并发连接,实际生产环境中可以支撑2~4万并发连接数。

2、内存消耗少
Nginx+PHP(FastCGI)服务器,
在3万并发连接下,开启10个Nginx进程消耗150MB内存,15MB*10=150MB,
开启的64个PHP-CGI进程消耗1280内存,20MB*64=1280MB,加上系统自身消耗的内存,
总共消耗不到2GB的内存。
 
3、成本低廉
购买F5BIG-IP、NetScaler等硬件负载均衡交换机,需要十多万到几十万人民币,而Nginx为开源软件,采用的是2-clause BSD-like协议,可以免费试用,并且可用于商业用途。

4、配置文件非常简单
网络和程序一样通俗易懂,即使,非专用系统管理员也能看懂。

5、内置的健康检查功能
如果NginxProxy后端的某台Web服务器宕机了,不会影响前端的访问。

6、节省带宽
支持GZIP压缩,可以添加浏览器本地缓存的Header头。

7、稳定性高
用于反向代理,宕机的概率微乎其微。

8、支持热部署
Nginx支持热部署,它的自动特别容易,并且,几乎可以7天*24小时不间断的运行,即使,运行数个月也不需要重新启动,还能够在不间断服务的情况下,对软件版本进行升级。

Nginx反向代理配置:

Tomcat集群:

大佬参考地址:https://www.cnblogs.com/liaokailin/p/3968891.html

修改Tomcat默认端口号

tomcat默认的端口号(缺省端口),怎么修改

tomcat默认的端口是8080

修改Server.xml中 Connector的port属性即可,

如果同一个tomcat要启动多个tomcat ,还需要修改Server里面的port端口 以及Connector AJP协议的port端口

<Server port="8006" shutdown="SHUTDOWN">

<Connector  port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" redirectPort="8443" />

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />	  

tomcat中部署项目的方式

部署的三种方案:

1.直接将web项目 或 war包 拷贝至webapps目录下即可:

2.在配置文件Server.xml中找到标签,在里面 加上下面一句:

<Context docBase="项目的路径" path="虚拟目录" />

3.conf/Catalina/localhost 创建 xxx.xml文件,在文件中指定项目路径,该项目的访问路径 即文件的名字

 <Context docBase="项目的路径" />

PS:ROOT文件夹内是根目录下的项目,访问该项目不需要加虚拟目录

tomcat中运行的生产项目,出现问题如何排查?

出现问题首先去tomcat的logs目录下,查看日志文件中有没有什么错误信息。

catalina.201X-XX-XX.log记录启动时日志信息

localhost.201X-XX-XX.log记录各个webapp下项目的日志信息

tail -f fileName    
#会把 filename 文件里的最尾部的内容显示在屏幕上,并且不断刷新,只要 filename 更新就可以看到最新的文件内容。

如:日志中发现

java.lang.StackOverflowError异常,这个是栈内存溢出

可能在哪些地方发生内存泄漏了,如果通过异常能够找到溢出的发生地,则优化对应代码。

如果没有发现,则可以通过 JvisualVM 等工具监控Tomcat的运行情况


学习更多JAVA知识与技巧,关注与私信博主(学习)免费学习领取JAVA 课件,源码,安装包,还有最新

大厂面试资料等等等

最近发表
标签列表