最近打算离职去我所向往的城市,公司交接项目之余写一些心得体会,方便以后查看以及给新的同学一些启发。
tomcat优化
对于tomcat,优化大致从内存、缓存、连接、协议以及服务器参数这么几个方向来做。
1、内存
内存优化主要是对于启动的优化,在 tomcat 的启动脚本 catalina.sh 中设置 java_OPTS 参数
-server 启用jdk 的 server 版
-Xms java虚拟机初始化时的最小内存
-Xmx java虚拟机可使用的最大内存
-XX: PermSize 内存永久保留区域
-XX:MaxPermSize 内存最大永久保留区域
这些参数需要根据服务器的实际内存来设置
示例:
JAVA_OPTS=’-Xms1024m -Xmx2048m -XX: PermSize=256M -XX:MaxNewSize=256m -XX:MaxPermSize=256m’
2、缓存
1、tomcat的maxThreads(最大线程数)、acceptCount(最大排队数)
maxThreads:tomcat启动的最大线程数,即同时处理的任务个数,默认值为200
acceptCount:当tomcat启动的线程数达到最大时,接受排队的请求个数,默认值为100
这两个参数的作用就是启动后,请求过来时,如果最大连接数没超过maxThreads时,tomcat会启动一条线程处理,如果达到最大连接数,如果线程排队数量未超过acceptCount时,tomcat会把请求放入队列,等待空闲线程,如果超过最大排队数,那Tomcat会直接拒绝这次请求,返回connection refused。
maxThreads配置:考虑CPU的运算能力:这个时候可能需要大家了解一些计算机CPU的运算流程,CPU在对线程进行处理的时候,是通过时间片切换的(相信读这篇文章的同学都了解线程间的抢占),如果请求量过大,CPU在工作时会加载全部线程,然后随机切换线程,这个时候CPU会出现一种情况,保存现在处理的记录,切换另一条线程并读取记录,中间的切换就叫时间片切换,这个时候线程很多,CPU处理时不停的在时间片之间切换,浪费巨量的时间,这样整个响应就会变得很慢。
我在测试时在请求在2000出头得时候,单次请求得响应时间会急剧的增加。所以多线程并不一定等于高效率。当cpu核心数<线程数时,cpu就需要在多个线程直接来回切换,以保证每个线程都会获得cpu时间,即通常我们说的并发执行。
最好的做法是:在不断测试的基础上,不断调整、优化,才能得到最合理的配置。符合你服务器CPU的一个最优值。当然maxThreads 配置要结合 JVM -Xmx 参数调整,也就是要考虑内存开销。
acceptCount的配置:我一般设置的和maxThreads一样大,这个值主要根据应用的访问峰值与平均值来权衡配置的。
3、连接
我这里的连接,也就是并发的优化,从两个方面入手:
1、调整连接器connector的并发处理能力:maxThreads 最大线程数。
minSpareThreads : Tomcat初始化时创建的 socket 线程数
maxSpareThreads: Tomcat连接器的最大空闲 socket 线程数
enableLookups : 是否反查域名,取值为: true 或 false 。为了提高处理能力,应设置为 false
redirectPort: 在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口
acceptAccount: 监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads )
connectionTimeout:连接超时
minProcessors: 服务器创建时的最小处理线程数
maxProcessors: 服务器同时最大处理线程数
URIEncoding: URL统一编码
其中和最大连接数相关的参数为maxProcessors和acceptCount。如果要加大并发连接数,应同时加大这两个参数。当然如果是太大的并发量,我建议搭建集群使用负载均衡来减缓服务器压力。
2、压缩优化
compression=''on'' 打开压缩功能
compressionMinSize="2048" 启用压缩的输出内容大小,默认为2KB
noCompressionUserAgents="gozilla,traviata" 对于以下的浏览器,不启用压缩
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 哪些资源类型需要压缩
Tomcat 的压缩是在客户端请求服务器对应资源后,从服务器端将资源文件压缩,再输出到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程 HTML、CSS、Javascript和Text,它可以节省40% 左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP、JSP、ASP、Servlet,SHTML等输出的网页也能进行压缩,压缩效率也很高。但是, 压缩会增加 Tomcat 的负担,因此最好采用Nginx + Tomcat 或者 Apache + Tomcat 方式,将压缩的任务交由 Nginx/Apache 去做。
3、协议
方式 | 参数更改 | 原理 |
关闭AJP端口 | <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> --> | AJP是为 Tomcat 与 HTTP 服务器之间通信而定制的协议,能提供较高的通信速度和效率。如果tomcat前端放的是apache的时候,会使用到AJP这个连接器。若tomcat未与apache配合使用,因此不使用此连接器,因此需要注销掉该连接器。 |
bio模式 | <Cinnector port="8009" protocol="org.apache.coyote.http11.Http11NioProtocol" > | 默认的模式,性能非常低下,没有经过任何优化处理和支持. |
nio模式 | <Cinnector port="8009" protocol="org.apache.coyote.http11.Http11NioProtocol" > | nio(new I/O),是Java SE 1.4及后续版本提供的一种新的I/O操作方式(即java.nio包及其子包)。Java nio是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,因此nio也被看成是non-blocking I/O的缩写。它拥有比传统I/O操作(bio)更好的并发运行性能。 |
apr模式 | 目前Tomcat 8.x默认情况下全部是运行在nio模式下,而apr的本质就是使用jni技术调用操作系统底层的IO接口,所以需要提前安装所需要的依赖, 首先是需要安装openssl和apr,命令如下: yum -y install openssl-devel 安装之后,去tomcat官网下载native组件,native可以看成是tomcat和apr交互的中间环节,下载地址是:http://tomcat.apache.org/download-native.cgi 这里下载最新的版本1.2.10 解压之后上传至服务器执行解压并安装: tar -xvzf tomcat-native-1.2.10-src.tar.gz -C /usr/local 然后进入tomcat安装目录,编辑配置文件:conf/server.xml 将默认的protocol="HTTP/1.1"修改为protocol="org.apache.coyote.http11.Http11AprProtocol"
apr引入方法: 配置tomcat安装目录下:bin/catalina.sh文件引入apr,推荐这种方式: 在原有变量JAVA_OPTS后面追加对应的配置即可,添加一行新的就可以:JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/apr/lib" | apr是从操作系统级别解决异步IO问题,大幅度提高服务器的并发处理性能,也是Tomcat生产环境运行的首选方式 |
4、服务器参数:
优化网卡驱动可以有效提升性能,这个对于集群环境工作的时候尤为重要。由于我们采用了linux服务器,所以优化内核参数也是一个非常重要的工作。给一个参考的优化参数:
01、 修改/etc/sysctl.cnf文件,在最后追加如下内容:
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
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 = 1024 65000 net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_timestamps = 0
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 = 65536
02、 保存退出,执行sysctl -p生效