个人分类: tomcat
不要单纯为了调优而去调优,应该有针对性的去发现不足,解决问题,以提高性能。
所以,调优的前提是做好各种监控分析,包括服务器基础资源使用、各个应用运行状况、代码质量、数据库状况、等等,根据业务的并发,服务器资源,以及存在的问题,有针对性的去优化。
==========正文==============
性能的提升,主要从以下几个方面入手:
1,架构调优
负载均衡,高可用,nginx tomcat 动静分离,容器化 等, 不具体阐述
2 ,代码调优
(1),代码编写规范。
(2),pmd 、findbug、sonar 等工具,检测问题,并优化。 不具体阐述。
3,tomcat 相关参数优化,jvm调优。
(1),连接数,线程数,缓存,修改server.xml。
打开被注释的默认连接池配置
默认配置:
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
修改实例:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150"
minSpareThreads="100"
prestartminSpareThreads="true"
maxQueueSize="100"/>
参数讲解:
- name: 线程名称
- namePrefix: 线程前缀
- maxThreads : 最大并发连接数,不配置时默认200,一般建议设置500~ 800 ,要根据自己的硬件设施条件和实际业务需求而定。
- minSpareThreads:Tomcat启动初始化的线程数,默认值25
- prestartminSpareThreads:在tomcat初始化的时候就初始化minSpareThreads的值, 不设置trueminSpareThreads 的值就没啥效果了 。
- maxQueueSize: 最大的等待队列数,超过则拒绝请求
修改连接配置
默认配置:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改配置:
connectionTimeout="20000"
redirectPort="8443"
executor="tomcatThreadPool"
enableLookups="false"
maxIdleTime="60000"
acceptCount="100"
maxPostSize="10485760"
acceptorThreadCount="2"
disableUploadTimeout="true"
URIEncoding="utf-8"
keepAliveTimeout ="6000"
maxKeppAliveRequests="500"
/>
参数讲解:
- port:连接端口。
- protocol:连接器使用的传输方式。
- executor: 连接器使用的线程池名称
- enableLookups:禁用DNS 查询
- maxIdleTime:线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为6000(1分钟),单位毫秒。
- acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理,默认设置 100 。
- maxPostSize:限制 以FORM URL 参数方式的POST请求的内容大小,单位字节,默认是 2097152(2兆),10485760 为 10M。如果要禁用限制,则可以设置为 -1。
- acceptorThreadCount: 用于接收连接的线程的数量,默认值是1。一般这个指需要改动的时候是因为该服务器是一个多核CPU,如果是多核 CPU 一般配置为 2。
- disableUploadTimeOut:允许Servlet容器,正在执行使用一个较长的连接超时值,以使Servlet有较长的时间来完成它的执行,默认值为false
- keepAliveTimeout - 表示在下次请求过来之前,tomcat保持该连接多久。这就是说假如客户端不断有请求过来,且未超过过期时间,则该连接将一直保持。
- maxKeepAliveRequests -表示该连接最大支持的请求数。超过该请求数的连接也将被关闭(此时就会返回一个Connection: close头给客户端)。 (maxKeepAliveRequests="1"代表禁用长连接)(1表示禁用,-1表示不限制个数,默认100个。一般设置在100~200之间)
压缩会增加Tomcat负担,最好采用Nginx Tomcat 或者 Apache Tomcat 方式,压缩交由Nginx/Apache 去做。
Tomcat 的压缩是在客户端请求服务器对应资源后,从服务器端将资源文件压缩,再输出到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的 浏览过程 HTML、CSS、Javascript和Text,它可以节省40% 左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP、JSP、ASP、Servlet,SHTML等输出的网页也能进行压缩,压缩效率也很高。
管理AJP端口
AJP是为 Tomcat 与 HTTP 服务器之间通信而定制的协议,能提供较高的通信速度和效率。如果tomcat前端放的是apache的时候,会使用到AJP这个连接器。 默认是开启的。如果不使用apache,注释该连接器。
<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->
(2),apr 模式。
(Apache Portable Runtime/Apache可移植运行库),是Apache HTTP服务器的支持库。你可以简单地理解为,Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从操作系统级别解决异步IO问题,从而大大地提高Tomcat对静态文件的处理性能。
要tomcat支持apr,必须要安装apr和native,这样tomcat可以利用apache的apr接口,使用操作系统的部分本地操作,从而提升性能。
https://tomcat.apache.org/native-doc/ (官方文档)
官方要求:
APR 1.2 development headers (libapr1-dev package)
OpenSSL 1.0.2 development headers (libssl-dev package)
JNI headers from Java compatible JDK 1.4
GNU development environment (gcc, make)
1, 下载
yum install expat-devel gcc make lib* -y
wget http://apache.cs.utah.edu/apr/apr-1.6.3.tar.gz
wget http://apache.cs.utah.edu/apr/apr-util-1.6.1.tar.gz
wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-connectors/native/1.2.16/source/tomcat-native-1.2.16-src.tar.gz
weget https://www.openssl.org/source/openssl-1.1.1-pre7.tar.gz
2, 编译 安装
先编译安装 apr
cd /usr/local/src/apr-1.5.2
./configure --prefix=/usr/local/apr
make && make install
安装 openssl
tar zxvf openssl-1.1.0f.tar.gz
cd openssl-1.1.0f
./config --prefix=/usr/local/openssl
make -j 4 && make install
安装apr-util
cd /usr/local/src/apr-util-1.5.4
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
make && make install
安装 tomcat-native
cd /usr/local/src/tomcat-native-1.2.16-src/native
./configure --with-apr=/usr/local/apr --with-ssl=/usr/local/openssl
make && make install
3,设置 Tomcat 整合 APR
编辑$TOMCAT_HOME/bin/catalina.sh文件,在虚拟机启动参数JAVA_OPTS中添加java.library.path参数,指定apr库的路径
JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/apr/lib/"
指定运行模式,将protocol从HTTP/1.1改成org.apache.coyote.http11.Http11AprProtocol
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
*** />
重启tomcat
(3),JVM 调优:
这一点需要去了解较多的基础知识,比如:了解堆栈内存,了解jvm 垃圾收集器,了解jvm 性能监控常用工具,能够读懂gc日志 等。。这里不详细解读。
jdk8 参考JVM 配置:
JDK 1.8中 PermSize 和 MaxPermGen 已经无效。JDK 1.8 中已经不存在永久代的结论 而以 元空间 代替。
修改 catalina.sh (4G 内存机器参考配置):
JAVA_OPTS="-Xms2G -Xmx2G -Xmn512m -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M -XX: UseConcMarkSweepGC -XX: CMSClassUnloadingEnabled -XX: HeapDumpOnOutOfMemoryError -verbose:gc -XX: PrintGCDetails -XX: PrintGCTimeStamps -XX: PrintGCDateStamps -Xloggc:/appl/gc.log -XX:CMSInitiatingOccupancyFraction=75 -XX: UseCMSInitiatingOccupancyOnly"
参数解释:
-Xms2G 初始分配的堆内存
-Xmx2G 最大允许分配的堆内存,这两个配成一样。
-Xmn512m 年轻代大小
-XX:MetaspaceSize=512M 初始元空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
-XX:MaxMetaspaceSize=512M
-XX: UseConcMarkSweepGC 并发标记清除(CMS)收集器
-XX: CMSClassUnloadingEnabled
-XX: HeapDumpOnOutOfMemoryError 表示当JVM发生OOM时,自动生成DUMP文件。
-XX:HeapDumpPath=${目录}参数表示生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java_<pid><date><time>_heapDump.hprof。
-verbose:gc 输出GC日志 , -XX: PrintGC 与 -verbose:gc 是一样的,可以认为-verbose:gc 是 -XX: PrintGC的别名.
-XX: PrintGCDetails 打印GC详细信息
-XX: PrintGCTimeStamps 打印gc时间戳
-XX: PrintGCDateStamps
-Xloggc:/appl/gc.log 定义gc日志目录
-XX:CMSInitiatingOccupancyFraction=75 是指设定CMS在对内存占用率达到75%的时候开始GC(因为CMS会有浮动垃圾,所以一般都较早启动GC);
-XX: UseCMSInitiatingOccupancyOnly 只是用设定的回收阈值(上面指定的75%),如果不指定,JVM仅在第一次使用设定值,后续则自动调整
4,数据库调优
mysql的 架构 、运行参数、分库分表、sql优化等等。不具体阐述。
5,操作系统调优
硬件: CPU、内存、硬盘、带宽 。 这个属于 不差钱 性质的优化。人民币玩家 不废话。
系统:内核参数调. (最大 打开文件数、进程数,等)
linux 服务器,centons 7 .
(1),修改 最大打开文件数。 (linux 一切皆文件)
系统级打开最大文件句柄的数量 (一般 不做 调整,除非 并发 特别大 )
阿里云 默认:
cat /proc/sys/fs/file-max
382457
腾讯云 默认:
cat /proc/sys/fs/file-max
98544
永久生效的修改方法,修改文件,文件末尾加入配置内容:
# vim /etc/sysctl.conf
fs.file-max = 2000000
然后执行命令,使修改配置立即生效:
# sysctl -p
进程 级别 ,最大打开文件句柄数 设置。 (默认都小于 系统级的 大小)
在/etc/security/limits.conf 最后增加: (参考的 腾讯云默认 配置)
* soft nproc 100001 #警告设定所有用户最大打开进程数为10001
* hard nproc 100001 # 严格设定所有用户最大打开进程数为100001
* soft nofile 100001 # 警告设定所有用户最大打开文件数为100001
* hard nofile 100002 # 严格设定所有用户最大打开文件数为100002
1soft 表示警告的设定,可以超过这个设定值,但是超过会有警告信息
2 hard 表示严格的设定,必定不能超过这个设定的值
修改以后,重新登录后生效。
对于服务器,一般修改进程级的最大打开文件句柄数即可(系统默认1024,有点小)。一般不需要调整系统级的最大数。
如果出现了达到系统级别最大限制时,也需要同步调整系统级的最大数的。
(2)、TCP 相关参数优化。(参数太多,选取了 常见的几个)
修改 /etc/sysctl.conf
生效: sysctl -p
net.ipv4.tcp_mem = 196608 262144 393216
#(4G 内存机器 使用,TCP连接最多约使用1.6GB内存 , 393216*4096/1024/1024=1.6G)
#内核分配给TCP连接的内存hh ,单位是Page,1 Page = 4096 Bytes
net.ipv4.tcp_mem = 524288 699050 1048576
#(8G 内存使用,TCP连接最多约使用4GB内存)
#为每个TCP连接分配的读、写缓冲区内存大小,单位是Byte
net.ipv4.tcp_rmem = 4096 8192 4194304
net.ipv4.tcp_wmem = 4096 8192 4194304
# 最小内存 缺省内存 最大内存
# 一般按照缺省值分配,上面的例子就是读写均为8KB,共16KB
#1.6G 内存服务器, TCP内存能容纳的连接数,约为 1600MB/16KB = 100K = 10万
#4.G TCP内存能容纳的连接数,约为 4000MB/16KB = 250K = 25万
net.core.somaxconn= 4000
#(端口最大的监听队列的长度)
#同时,修改下全局配置
# echo 4000 > /proc/sys/net/core/somaxconn 定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128,
net.ipv4.tcp_syncookies = 1
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭;
net.ipv4.tcp_fin_timeout = 30
#修改系統默认的 TIMEOUT 时间。
net.ipv4.tcp_keepalive_time = 1200
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
net.ipv4.ip_local_port_range = 10000 65000
#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为10000到65000。
#(注意:这里不要将最低值设的太低,否则可能会占用掉正常的端口!)
net.ipv4.tcp_max_syn_backlog = 8192
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000
#表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默 认为180000,改为5000。
net.ipv4.tcp_max_orphans = 65536
#当orphans达到32768个时,会报Out of socket memory,此时占用内存 32K*64KB=2048MB=2GB
#(每个孤儿socket可占用多达64KB内存),实际可能小一些
net.ipv4.tcp_orphan_retries = 1
#孤儿socket废弃前重试的次数,重负载web服务器建议调小,设置较小的数值,可以有效降低orphans的数量
net.ipv4.tcp_retries2
#活动TCP连接重传次数,超过次数视为掉线,放弃连接。缺省值:15,建议设为 2或者3.
net.ipv4.tcp_synack_retries
#TCP三次握手的syn/ack阶段,重试次数,缺省5,设为2-3
net.core.netdev_max_backlog = 2048
# 网络设备的收发包的队列大小