1. 优化tomcat参数
一个典型的server.xml配置
<Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" connectionTimeout="20000" acceptCount="1000" redirectPort="443" compression="on" compressionMinSize="1024" enableLookups="false" URIEncoding="UTF-8" useBodyEncodingForURI="true" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"/>
详细的参数说明, 参考 https://tomcat.apache.org/tomcat-7.0-doc/config/index.html (Tomcat7)下面的Connector,
enableLookups
设为false, 禁止request.getRemoteHost()反查host
maxHeaderCount
对request header数量的限制, 默认为100, 如果设置小于0, 则不限制
maxParameterCount
对request参数数量的限制, 默认为1000, 如果设置小于0, 则不限制
protocol
优先使用apr
URIEncoding
默认是ISO-8859-1,
acceptCount
最大请求队列长度, 默认为100
2. 优化应用配置
1) 在web.xml里, 不要将整个 /* 映射给spring, 而是用 *.html, *.jsp之类的url-pattern
2) 在web.xml里增加对图片, js, css的缓存时间(实际使用时未发现header里面Expires的变化, 依然是1970.01.01, 但是status确实变成了304 Not Modified.
<filter> <filter-name>ExpiresFilter</filter-name> <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class> <init-param> <param-name>ExpiresByType image</param-name> <param-value>access plus 10 minutes</param-value> </init-param> <init-param> <param-name>ExpiresByType text/css</param-name> <param-value>access plus 10 minutes</param-value> </init-param> <init-param> <param-name>ExpiresByType application/javascript</param-name> <param-value>access plus 10 minutes</param-value> </init-param> </filter> <filter-mapping> <filter-name>ExpiresFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>
3) 对于启用了SSL的tomcat, 需要在conf/context.xml里面加上这个
<Valve className="org.apache.catalina.authenticator.BasicAuthenticator" dis ableProxyCaching="false" />
这样Tomcat就不会对输出的各种资源文件强行加上Cache-Control:private 和 Expires:Thu, 01 Jan 1970 08:00:00 CST 了.
3. 优化网络内核参数
█ 减少处于FIN-WAIT-2连接状态的时间,使系统可以处理更多的连接。
net.ipv4.tcp_fin_timeout = 2
# 如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。
# 对端可以出错并永远不关闭连接,甚至意外当机,缺省值是60秒。
# 2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN-WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。
█ 以下两参数可解决生产场景中大量连接的Web(cache)服务器中TIME_WAIT过多问题。
net.ipv4.tcp_tw_reuse = 1
# 表示开启重用。允许将TIME-WAIT sockets重新用于新的 TCP 连接,默认为 0 表示关闭。
█ 打开TIME-WAIT套接字重用及回收功能。
net.ipv4.tcp_tw_recycle = 1
# 表示开启TCP连接中TIME-WAIT sockets的快速收回功能,默认为 0 ,表示关闭。
█ 当keepalive起用的时候,TCP发送keepalive消息的频度,缺省是2小时,改为20分钟。
net.ipv4.tcp_keepalive_time = 1200
█ 允许系统打开的端口范围
net.ipv4.ip_local_port_range = 4000 65000
# 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为4000到65000。
█ 提高系统支持的最大SYN半连接数(默认1024)
net.ipv4.tcp_max_syn_backlog = 16384
# 表示SYN队列的长度,默认为1024,加大队列长度为16384,可以容纳最多等待连接的网络连接数。
[root@centos5 ~]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog
1024
█ 系统同时保持TIME_WAIT套接字的最大数量
net.ipv4.tcp_max_tw_buckets = 5000
# 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为 5000。
# 对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
█ 路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由,默认是300。
net.ipv4.route.gc_timeout = 100
█ 在内核放弃建立连接之前发送SYN包的数量。
net.ipv4.tcp_syn_retries = 1
█ 减少系统SYN连接重试次数(默认是5)
net.ipv4.tcp_synack_retries = 1
# 为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。
# 也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。
█ 设置系统对最大跟踪的TCP连接数的限制(CentOS 5.6无此参数)
net.ipv4.ip_conntrack_max = 25000000
█ tcp_max_orphans :INTEGER 系统所能处理不属于任何进程的TCP sockets最大数量
缺省值是8192。假如超过这个数量﹐那么不属于任何进程的连接会被立即reset,并同时显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐千万不要依赖这个或是人为的降低这个限制(这个值Redhat AS版本中设置为32768,但是很多防火墙修改的时候,建议该值修改为2000)
net.ipv4.tcp_max_orphans = 3276800
█ tcp_mem(3个INTEGER变量):low, pressure, high
low:当TCP使用了低于该值的内存页面数时,TCP不会考虑释放内存。(理想情况下,这个值应与指定给 tcp_wmem 的第 2 个值相匹配 - 这第 2 个值表明,最大页面大小乘以最大并发请求数除以页大小 (131072 * 300 / 4096)。 )
net.ipv4.tcp_mem = 94500000 915000000 927000000
█ 在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。缺省设置:300
net.core.netdev_max_backlog = 10240
█ 最大的等待连接完成的套接字队列大小,即并发连接数。
高负载服务器和受到Dos攻击的系统也许会因为这个队列被塞满而不能提供正常服务。 默认为128,推荐在1024-4096之间,根据机器和实际情况需要改动,数字越大占用内存也越大。
net.core.somaxconn = 2048
█ 发送套接字缓冲区大小的缺省值(以字节为单位)。缺省设置:110592
net.core.wmem_default = 8388608
█ 发送套接字缓冲区大小的最大值(以字节为单位)。缺省设置:131071
net.core.wmem_max = 16777216
█ 接收套接字缓冲区大小的缺省值(以字节为单位)。缺省设置:110592
net.core.rmem_default = 8388608
█ 接收套接字缓冲区大小的最大值(以字节为单位)。缺省设置:131071
net.core.rmem_max = 16777216
供参考的配置, 添加到 /etc/sysctl.conf 最后, 再执行sysctl -p生效
net.core.netdev_max_backlog = 10240 net.core.somaxconn = 2048 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.ip_local_port_range = 10240 65000 net.ipv4.route.gc_timeout = 100 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 1200 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_mem = 94500000 915000000 927000000 net.ipv4.tcp_max_orphans = 3276800 net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_max_tw_buckets = 5000
提升Tomcat的启动速度
Tomcat 在kvm虚机下启动速度超慢, 大部分都是由于/dev/random太慢阻塞引起. 可以通过以下命令检查服务器是否属于这种情况
# 检查cpu是否支持 rdrand, 支持的话速度都不慢 cat /proc/cpuinfo | grep rdrand # 检查随机数生成池的大小, 正常应该在3000以上, 太小肯定会影响tomcat启动 cat /proc/sys/kernel/random/entropy_avail # 测试 /dev/random速度, 正常应该在几秒之内完成 dd if=/dev/random of=random.dat count=1024
对于/dev/random速度很慢的虚机, 可以通过启用 rngd 服务并使用 /dev/urandom 伪随机数源来优化tomcat的启动, 以下适用于Centos6.x
# 安装 rngd yum install rng-tools # 尝试启动 service rngd start # 如果报错的话, 配置随机数生成源 vi /etc/sysconfig/rngd # Add extra options here EXTRAOPTIONS="-r /dev/urandom"
能成功启动后, 将rngd加入开机启动
chkconfig --level 2345 rngd on
再测试 dd if=/dev/random of=random.dat count=1024, 这时候速度就很快了