# TomCat 优化性能 *web 技术栏* Web 服务器 TomCat 服务,性能优化方法! ## 目录 [TOC]  ## 内存方面优化 在bin目录下面的catalina.sh中添加如下 ``` JAVA_OPTS=-server -Xms8192m -Xmx8192m -Xmn1890m -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -verbose:gc -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=0 -XX:+UseParallelGC XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy -XX:CMSInitiatingOccupancyFraction=70 -XX:CMSFullGCsBeforeCompaction=0 -Xnoclassgc ``` - server:一定要作为第一个参数,在多个CPU时性能佳 - Xms:设置JVM最大可用内存。 默认是物理内存的1/64,一般设置为服务器配置的内存。 - Xmx:java heap最大值,此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。 - XX:PermSize:设定内存的永久保存区初始大小。缺省值为64M。 - XX:MaxPermSize:设定内存的永久保存区最大 大小。缺省值为64M。 - Xmn:young generation(年轻代)的heap大小。一般设置为Xmx的3、4分之一 - XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5 - XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6 - XX:MaxPermSize=16m:设置持久代大小为16m。 - verbose:gc:显示垃圾收集信息(在虚拟机发生内存回收时在输出设备显示信息) UseConcMarkSweepGC:设置年老代为并发收集。 - XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。 - XX:+UseParallelGC:年轻代垃圾收集器为并行收集器。 - XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。 - XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直打开。 CMSInitiatingOccupancyFraction:触发CMS收集器的内存比例。比如60%的意思就是说,当内存达到60%,就会开始进行CMS并发收集。 CMSFullGCsBeforeCompaction:设置在几次CMS垃圾收集后,触发一次内存整理。 - Xnoclassgc:禁用类垃圾回收,性能会高一点; ## Tomcat 线程优化 在server.xml中 可以编辑 `Connector` 标签,并将其中的线程数量设置的比较大! ``` <Connector port="80" protocol="HTTP/1.1" maxThreads="600" minSpareThreads="100" maxSpareThreads="500" acceptCount="700" connectionTimeout="20000"/> ``` - maxThreads="X" 表示最多同时处理X个连接 - minSpareThreads="X" 初始化X个连接 - maxSpareThreads="X" 表示如果最多可以有X个线程,一旦超过X个,则会关闭不在需要的线程 - acceptCount="X" 当同时连接的人数达到maxThreads时,还可以排队,队列大小为X.超过X就不处理 ## TomCat IO 优化 1:Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 2:JAVA NIO:又分为同步非阻塞IO,异步阻塞IO 与BIO最大的区别one request one thread.可以复用同一个线程处理多个connection(多路复用). 3.Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理 BIO、NIO、AIO适用场景分析: BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解. NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持. AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持. ### BIO 配置 可以通过直接修改 `server.xml` 实现,下面是一个配置示例! ```xml <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ``` ### NIO 配置 可以通过直接修改 `server.xml` 实现,下面是一个配置示例! ```xml <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" /> ``` ### AIO 配置 【Linux篇】 APR 的本机库包,TomCat 提供的是 win 版本,而非Linux,我们需要单独的下载源码,然后编译。 #### 安装 GCC 因此需要准备安装 gcc ``` apt install gcc ``` #### 安装 APR(如果已经安装可跳过) 也可以手动下载 [《Article/Files/89437257/apr-1.7.5.tar.gz》](https://diskmirror.lingyuzhao.top/DiskMirrorBackEnd/FsCrud/downLoad/1/Binary?fileName=Article/Files/89437257/apr-1.7.5.tar.gz) 的源码包。 ``` wget http://archive.apache.org/dist/apr/apr-1.7.5.tar.gz tar -zxvf apr-1.7.5.tar.gz cd apr-1.7.5 # /usr/local/apr 是 apr 的安装路径 ./configure --prefix=/usr/local/apr && make && make install ``` #### 安装 apr-utils(如果已经安装可跳过) [《Article/Files/89437257/apr-utils-1.6.3.tar.gz》](https://diskmirror.lingyuzhao.top/DiskMirrorBackEnd/FsCrud/downLoad/1/Binary?fileName=Article/Files/89437257/apr-utils-1.6.3.tar.gz) ``` wget http://archive.apache.org/dist/apr/apr-util-1.6.3.tar.gz tar -zxvf apr-util-1.6.3.tar.gz cd apr-util-1.6.3 # /usr/local/apr 是 apr 的安装路径 /usr/local/apr-utils 是期望的 apr-utils 的安装目录 ./configure --with-apr=/usr/local/apr/ --prefix=/usr/local/apr-utils && make && make install ``` ##### 可能出现的问题 ``` fatal error: expat.h: No such file or directory 35 | #include <expat.h> | ^~~~~~~~~ compilation terminated. ``` 错误信息 `fatal error: expat.h: No such file or directory` 表示编译器找不到 `expat.h` 头文件。expat 是一个用于解析 XML 的库,Tomcat Native 库可能需要它来支持某些功能。 为了解决这个问题,你需要安装 expat 开发库。在 Debian/Ubuntu 系统上,你可以使用以下命令来安装 expat 开发库: ``` apt-get install libexpat1-dev ``` #### 安装 openSSL(如果发生关于 openSSL 的错误的话) 如果版本不正确也需要在这里安装哦,它对 openSSL 的版本是有要求的,在这里我们是显示的 3.0.0 以及以上版本 因此我们选择了 `3.4.0` 版本进行下载和安装,安装过程比较长 需要编译! ``` wget https://github.com/openssl/openssl/releases/download/openssl-3.4.0/openssl-3.4.0.tar.gz tar -xzxf openssl-3.4.0.tar.gz cd openssl-3.4.0 # 注意这里需要加入 -fPIC参数,否则后面在安装tomcat native 组件会出错 ./config --prefix=/usr/local/openssl -fPIC&& make && make install ``` #### 进入到 tomcat-native 源码目录 如果没有准备到源码在这里可以直接下载 在这准备了两个版本,对应不同的 TomCat 我们可以直接将对应版本的源码下载并解压好 [《Article/Files/89437257/tomcat-native-2.0.8-src.tar.gz》](https://diskmirror.lingyuzhao.top/DiskMirrorBackEnd/FsCrud/downLoad/1/Binary?fileName=Article/Files/89437257/tomcat-native-2.0.8-src.tar.gz) [《Article/Files/89437257/tomcat-native-1.3.1-src.tar.gz》](https://diskmirror.lingyuzhao.top/DiskMirrorBackEnd/FsCrud/downLoad/1/Binary?fileName=Article/Files/89437257/tomcat-native-1.3.1-src.tar.gz) 也可以解压 `$TOMCAT_HOME/bin` 目录下 `tomcat-native.tar.gz` 文件 ``` root@gust-desktop:/opt/pag/tomcat-native-2.0.8-src# ll 总用量 128 drwxr-xr-x 7 root root 4096 11月 11 13:18 ./ drwxr-xr-x 3 root root 4096 11月 11 13:18 ../ -rwxrwxrwx 1 root root 2047 7月 18 02:22 build.properties.default* -rwxrwxrwx 1 root root 12613 7月 18 02:22 build.xml* -rwxrwxrwx 1 root root 4982 7月 18 02:23 CHANGELOG.txt* -rwxrwxrwx 1 root root 29526 7月 18 02:22 CMakeLists.txt* drwxrwxrwx 5 root root 4096 11月 11 13:18 docs/ -rw-r--r-- 1 root root 760 7月 18 02:22 .gitignore -rwxrwxrwx 1 root root 2319 7月 18 02:22 HOWTO-RELEASE.txt* drwxrwxrwx 3 root root 4096 11月 11 13:18 java/ -rwxrwxrwx 1 root root 8393 7月 18 02:22 jnirelease.sh* -rwxrwxrwx 1 root root 11357 7月 18 02:22 LICENSE* drwxrwxrwx 7 root root 4096 11月 11 15:29 native/ -rwxrwxrwx 1 root root 411 7月 18 02:22 NOTICE* -rwxrwxrwx 1 root root 2538 7月 18 02:22 README.txt* drwxrwxrwx 3 root root 4096 11月 11 13:18 test/ drwxrwxrwx 5 root root 4096 11月 11 13:18 xdocs/ root@gust-desktop:/opt/pag/tomcat-native-2.0.8-src# cd ./native/ root@gust-desktop:/opt/pag/tomcat-native-2.0.8-src/native# pwd /opt/pag/tomcat-native-2.0.8-src/native ``` #### 执行命令 ``` ./configure --with-apr=/usr/local/apr --with-ssl=/usr/local/openssl && make && make install ``` #### 查看是否存在 libtcnative 库文件 值得注意的是,我们在这里安装了两个不同的版本,这是为了确保各个版本的 TomCat 都可以访问到这个库文件的正确版本! ``` drwxr-xr-x 3 root root 4096 11月 11 18:25 ./ drwxr-xr-x 6 root root 4096 11月 11 16:04 ../ -rw-r--r-- 1 root root 10883 11月 11 16:04 apr.exp -rw-r--r-- 1 root root 2498206 11月 11 16:04 libapr-1.a -rwxr-xr-x 1 root root 964 11月 11 16:04 libapr-1.la* lrwxrwxrwx 1 root root 17 11月 11 16:04 libapr-1.so -> libapr-1.so.0.7.5* lrwxrwxrwx 1 root root 17 11月 11 16:04 libapr-1.so.0 -> libapr-1.so.0.7.5* -rwxr-xr-x 1 root root 1352184 11月 11 16:04 libapr-1.so.0.7.5* -rw-r--r-- 1 root root 2136764 11月 11 18:25 libtcnative-1.a -rwxr-xr-x 1 root root 1072 11月 11 18:25 libtcnative-1.la* lrwxrwxrwx 1 root root 22 11月 11 18:25 libtcnative-1.so -> libtcnative-1.so.0.3.1* lrwxrwxrwx 1 root root 22 11月 11 18:25 libtcnative-1.so.0 -> libtcnative-1.so.0.3.1* -rwxr-xr-x 1 root root 1253064 11月 11 18:25 libtcnative-1.so.0.3.1* -rw-r--r-- 1 root root 719280 11月 11 18:03 libtcnative-2.a -rwxr-xr-x 1 root root 1072 11月 11 18:03 libtcnative-2.la* lrwxrwxrwx 1 root root 22 11月 11 18:03 libtcnative-2.so -> libtcnative-2.so.0.0.8* lrwxrwxrwx 1 root root 22 11月 11 18:03 libtcnative-2.so.0 -> libtcnative-2.so.0.0.8* -rwxr-xr-x 1 root root 459504 11月 11 18:03 libtcnative-2.so.0.0.8* drwxr-xr-x 2 root root 4096 11月 11 16:04 pkgconfig/ root@gust-desktop:/usr/local/apr/lib# pwd /usr/local/apr/lib ``` #### 配置环境变量 ``` # 设置 LD_LIBRARY_PATH 确保其中指向的文件有我们的 libtcnative 库文件 TomCat 会在这里读取! export LD_LIBRARY_PATH=/usr/local/apr/lib/:$LD_LIBRARY_PATH # 这是一个优化措施,根据服务器来配置即可! export JAVA_OPTS="-Xms512m -Xmx1536m -XX:PermSize=256m -XX:MaxPermSize=512m" ``` #### 修改 server.xml ``` <!-- 443 号端口访问的配置 --> <Connector SSLEnabled="true" maxParameterCount="1000" maxThreads="150" port="***" <!-- 这里是关键!在这里启用了 apr 的协议处理器 --> protocol="org.apache.coyote.http11.Http11AprProtocol" defaultSSLHostConfigName="www.lingyuzhao.top" maxPostSize="536870912"> <!-- 这里省略其它配置 --> </Connector> ``` ### 启动 TomCat 在下面会展示出一些日志,其中就可以看到成功启用了 apr ``` 11-Nov-2024 18:26:10.441 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent 使用APR版本[1.7.5]加载了基于APR的Apache Tomcat本机库[1.3.1]。 11-Nov-2024 18:26:10.441 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR功能:IPv6[true]、sendfile[true]、accept filters[false]、random[true]、UDS [true]。 11-Nov-2024 18:26:10.441 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL配置:useAprConnector[false],useOpenSSL[true] 11-Nov-2024 18:26:10.449 信息 [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL成功初始化 [OpenSSL 3.4.0 22 Oct 2024] ``` ------ ***操作记录*** 作者:[root](https://www.lingyuzhao.top//index.html?search=1 "root") 操作时间:2024-11-13 10:52:52 星期三 【时区:UTC 8】 事件描述备注:保存/发布 中国 天津 [](如果不需要此记录可以手动删除,每次保存都会自动的追加记录)