共计 3854 个字符,预计需要花费 10 分钟才能阅读完成。
导读 | Tomcat 在使用的过程中会遇到很多报错,有些是程序的报错,但还有一部分是 tomcat 本身的报错,我们可以通过优化 tomcat 的初始配置来提高 tomcat 的性能。Tomcat 的优化主要体现在两方面:内存、并发连接数。 |
优化内存,主要是在 bin/catalina.bat 或 bin/catalina.sh 配置文件中进行。linux 上,在 catalina.sh 中添加:
JAVA_OPTS="-server -Xms1G -Xmx2G -Xss256K -Djava.awt.headless=true -Dfile.encoding=utf-8 -XX:MaxPermSize=256m -XX:PermSize=128M -XX:MaxPermSize=256M"
其中:
• -server:启用 jdk 的 server 版本。• -Xms:虚拟机初始化时的最小堆内存。• -Xmx:虚拟机可使用的最大堆内存。#-Xms 与 -Xmx 设成一样的值,避免 JVM 因为频繁的 GC 导致性能大起大落
• -XX:PermSize:设置非堆内存初始值, 默认是物理内存的 1 /64。• -XX:MaxNewSize:新生代占整个堆内存的最大值。• -XX:MaxPermSize:Perm(俗称方法区)占整个堆内存的最大值,也称内存最大永久保留区域。
1)错误提示:java.lang.OutOfMemoryError:Java heap space
Tomcat 默认可以使用的内存为 128MB,在较大型的应用项目中,这点内存是不够的,有可能导致系统无法运行。常见的问题是报 Tomcat 内存溢出错误,Outof Memory(系统内存不足)的异常,从而导致客户端显示 500 错误,一般调整 Tomcat 的 -Xms 和 -Xmx 即可解决问题,通常将 -Xms 和 -Xmx 设置成一样,堆的最大值设置为物理可用内存的最大值的 80%。
set JAVA_OPTS=-Xms512m-Xmx512m
2)错误提示:java.lang.OutOfMemoryError: PermGenspace
PermGenspace 的全称是 Permanent Generationspace, 是指内存的永久保存区域,这块内存主要是被 JVM 存放 Class 和 Meta 信息的,Class 在被 Loader 时就会被放到 PermGenspace 中,它和存放类实例 (Instance) 的 Heap 区域不同,GC(Garbage Collection)不会在主程序运行期对 PermGenspace 进行清理,所以如果你的应用中有很 CLASS 的话, 就很可能出现 PermGen space 错误,这种错误常见在 web 服务器对 JSP 进行 precompile 的时候。如果你的 WEB APP 下都用了大量的第三方 jar, 其大小超过了 jvm 默认的大小 (4M) 那么就会产生此错误信息了。解决方法:
setJAVA_OPTS=-XX:PermSize=128M
3)在使用 -Xms 和 -Xmx 调整 tomcat 的堆大小时,还需要考虑垃圾回收机制。如果系统花费很多的时间收集垃圾,请减小堆大小。一次完全的垃圾收集应该不超过 3 -5 秒。如果垃圾收集成为瓶颈,那么需要指定代的大小,检查垃圾收集的详细输出,研究垃圾收集参数对性能的影响。一般说来,你应该使用物理内存的 80% 作为堆大小。当增加处理器时,记得增加内存,因为分配可以并行进行,而垃圾收集不是并行的。
# 优化连接数,主要是在 conf/server.xml 配置文件中进行修改。
找到 Connectorport=”8080″ protocol=”HTTP/1.1″,增加 maxThreads 和 acceptCount 属性(使 acceptCount 大于等于 maxThreads),如下:
<Connectorport="8080" protocol="HTTP/1.1"connectionTimeout="20000" redirectPort="8443"acceptCount="500" maxThreads="400" />
其中:
• maxThreads:tomcat 可用于请求处理的最大线程数,默认是 200
• minSpareThreads:tomcat 初始线程数,即最小空闲线程数
• maxSpareThreads:tomcat 最大空闲线程数,超过的会被关闭
• acceptCount:当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理. 默认 100
在 server.xml 中增加 executor 节点,然后配置 connector 的 executor 属性,如下:
<Executorname="tomcatThreadPool" namePrefix="req-exec-"maxThreads="1000" minSpareThreads="50"maxIdleTime="60000"/>
<Connectorport="8080" protocol="HTTP/1.1"executor="tomcatThreadPool"/>
其中:
• namePrefix:线程池中线程的命名前缀
• maxThreads:线程池的最大线程数
• minSpareThreads:线程池的最小空闲线程数
• maxIdleTime:超过最小空闲线程数时,多的线程会等待这个时间长度,然后关闭
• threadPriority:线程优先级
注:当 tomcat 并发用户量大的时候,单个 jvm 进程确实可能打开过多的文件句柄,这时会报 java.net.SocketException:Too many open files 错误。可使用下面步骤检查:
• ps -ef |grep tomcat 查看 tomcat 的进程 ID,记录 ID 号,假设进程 ID 为 10001
• lsof -p 10001|wc -l 查看当前进程 id 为 10001 的 文件操作数
• 使用命令:ulimit -a 查看每个用户允许打开的最大文件数
1)BIO:一个线程处理一个请求。缺点:并发量高时,线程数较多,浪费资源。Tomcat7 或以下在 Linux 系统中默认使用这种方式。
2)NIO:利用 Java 的异步 IO 处理,可以通过少量的线程处理大量的请求。Tomcat8 在 Linux 系统中默认使用这种方式。Tomcat7 必须修改 Connector 配置来启动(conf/server.xml 配置文件):
<Connectorport="8080"protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000"redirectPort="8443"/>
3)APR(Apache Portable Runtime):从操作系统层面解决 io 阻塞问题。Linux 如果安装了 apr 和 native,Tomcat 直接启动就支持 apr。
安装 apr 以及 tomcat-native
yum -y install apr apr-devel
进入 tomcat/bin 目录,比如:
cd /opt/local/tomcat/bin/
tar xzfv tomcat-native.tar.gz
cd tomcat-native-1.1.32-src/jni/native
./configure --with-apr=/usr/bin/apr-1-config
make && make install
#注意最新版本的 tomcat 自带 tomcat-native.war.gz,不过其版本相对于 yum 安装的 apr 过高,configure 的时候会报错。
解决:yum remove apr apr-devel –y, 卸载 yum 安装的 apr 和 apr-devel, 下载最新版本的 apr 源码包,编译安装; 或者下载低版本的 tomcat-native 编译安装
安装成功后还需要对 tomcat 设置环境变量,方法是在 catalina.sh 文件中增加 1 行:
CATALINA_OPTS="-Djava.library.path=/usr/local/apr/lib"
#apr 下载地址:http://apr.apache.org/download.cgi
#tomcat-native 下载地址:http://tomcat.apache.org/download-native.cgi
修改 8080 端对应的 conf/server.xml
protocol=”org.apache.coyote.http11.Http11AprProtocol”
<Connector executor="tomcatThreadPool"
port="8080"
protocol="org.apache.coyote.http11.Http11AprProtocol"
connectionTimeout="20000"
enableLookups="false"
redirectPort="8443"
URIEncoding="UTF-8" />
PS: 启动以后查看日志 显示如下表示开启 apr 模式
Sep 19, 2016 3:46:21 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-apr-8081"]