Tomcat 性能优化

Tomcat 性能优化

优化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

优化应用配置

  • 在web.xml里, 不要将整个 /* 映射给spring, 而是用 *.html, *.jsp之类的url-pattern
  • 在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>
  • 对于启用了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 了.

优化网络内核参数

  • 减少处于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太慢阻塞引起.

Centos系统内在启动tomcat时, Tomcat的SessionID是通过SHA1PRNG算法计算得到的, SHA1算法需要一个密钥, 这个密钥在Tomcat启动的时候随机生成一个, 生成是使用了Linux随机函数生成器/dev/random. /dev/random会根据噪音产生随机数, 如果噪音不够它就会阻塞. Linux是通过I/O, 键盘终端、内存使用量、CPU利用率等方式来收集噪音的, 如果噪音不够生成随机数的时候就会被阻塞.

可以通过以下命令检查服务器是否属于这种情况

# 检查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

# 安装 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

Centos7

# 安装服务
yum install rng-tools
# 检查是否开机启动
systemctl is-enabled rngd
# 设置为开机启动
systemctl enable rngd
# 启动服务
systemctl start rngd

修改启动命令

vi /usr/lib/systemd/system/rngd.service
### 修改内容
ExecStart=/sbin/rngd -f -r /dev/urandom
### 修改内容结束
# 更新
systemctl daemon-reload
# 重启服务
systemctl restart rngd
# 查看状态
systemctl status rngd

再测试 dd if=/dev/random of=random.dat count=1024, 这时候速度就很快了

posted on 2015-05-17 01:12  Milton  阅读(558)  评论(0编辑  收藏  举报

导航