tomcat优化

一个服务的实际并发量收到很多方面因素的影响,大致归类一下如下:

1、数据库,这是web项目中最常见的瓶颈,解决方法一般都是通过cache
2、远程接口调用,解决方法是选择高性能的RPC框架,如dubbo+ZK等,使用长连接代替短连接
3、容器,容器本身的并发量是有上限的,所以大型系统都是分布式的
4、业务逻辑,复杂的业务逻辑肯定会花费更多的时间去处理,可以采用异步或多线程的方式解决
5.其他,如JVM调优,网络带宽,CDN加速等等很多其他因素
其中的容器就包括tomcat,tomcat是一个解压即可用的中间件,虽然默认配置可以使大多数正常运行,但是并不能发挥出服务最佳的性能。
本文主要记录对tomcat处理能力影响比较大的几个方面:
1、tomcat的运行模式,选对一个合适的运行模式会对tomcat的处理能力有质的影响
2、tomcat连接器中几个对并发量影响比较大的参数设置,类似超时时间,文件头大小等设置本篇不涉及。

一、tomcat连接器的几个关键参数


1、maxThreads


tomcat起动的最大线程数,即同时处理的任务个数,默认值为200
该值的大小直接影响tomcat的并发处理能力
maxThreads如何配置
maxThreads="800"
一般的服务器操作都包括量方面:1计算(主要消耗cpu),2等待(io、数据库等)
第一种极端情况,如果我们的操作是纯粹的计算,那么系统响应时间的主要限制就是cpu的运算能力,此时maxThreads应该尽量设的小,降低同一时间内争抢cpu的线程个数,可以提高计算效率,提高系统的整体处理能力。
第二种极端情况,如果我们的操作纯粹是IO或者数据库,那么响应时间的主要限制就变为等待外部资源,此时maxThreads应该尽量设的大,这样 才能提高同时处理请求的个数,从而提高系统整体的处理能力。此情况下因为tomcat同时处理的请求量会比较大,所以需要关注一下tomcat的虚拟机内 存设置和linux的open file限制。
maxThreads的配置绝对不是越大越好

2、acceptCount


当tomcat起动的线程数达到最大时,接受排队的请求个数,默认值为100

Linux内核协议栈为一个tcp连接管理使用两个队列,一个是半链接队列(用来保存处于SYN_SENT和SYN_RECV状态的请求),一个是全连接队列(accpetd队列)(用来保存处于established状态,但是应用层没有调用accept取走的请求)。默认的话半连接队列的长度是/proc/sys/net/ipv4/tcp_max_syn_backlog,默认是1024。如果开启了syncookies,那么基本上没有限制。

img

图片.png

tomcat有一个acceptor线程来accept socket连接,然后有工作线程来进行业务处理。对于client端的一个请求进来,在第三次握手之后,该连接进入到accept队列。tomcat的acceptor线程则负责从accept队列中取出该connection,接受该connection,然后交给工作线程去处理(读取请求参数、处理逻辑、返回响应等等;如果该连接不是keep alived的话,则关闭该连接,然后该工作线程释放回线程池,如果是keep alived的话,则等待下一个数据包的到来直到keepAliveTimeout,然后关闭该连接释放回线程池),然后自己接着去accept队列取connection(当当前socket连接超过maxConnections的时候,acceptor线程自己会阻塞等待,等连接降下去之后,才去处理accept队列的下一个连接)。acceptCount指的就是这个accept队列的大小

查看方法:

查看半连接队列:cat /proc/sys/net/core/somaxconn
查看半连接队列:cat /proc/sys/net/ipv4/tcp_max_syn_backlog

设置方法:

设置半连接队列大小:net.ipv4.tcp_max_syn_backlog = 16384
设置全连接队列大小:net.core.somaxconn = 16384

acceptCount的配置
acceptCount="1000"
这个值应该是主要根据应用的访问峰值与平均值来权衡配置的,通常可以使用默认值100或者设置为跟maxThreads相同

如果设的较小,可以保证接受的请求较快相应,但是超出的请求可能就直接被拒绝
如果设的较大,可能就会出现大量的请求超时的情况,因为我们系统的处理能力是一定的

3、maxConnections


这个值表示最多可以有多少个socket连接到tomcat上。NIO模式下默认是10000,对于BIO,默认的是maxThreads的值,APR /native的默认值是8192。
本参数与maxThreads是不同的,maxThreads是woker线程并发处理请求的最大数。也就是虽然client的socket连接上了,但是可能都在tomcat的task queue里头,等待worker线程处理返回响应。
maxConnections配置方法
maxConnections = "1000"

4、enableLookups

***如果你想request.getRemoteHost()的调用执行,以便返回的远程客户端的实际主机名的DNS查询,则设置为true。设置为false时跳过DNS查找,并返回字符串形式的IP地址(从而提高性能)。默认情况下,禁用DNS查找。


二、tomcat的几种HTTP连接器


*HTTP连接器即对应Connector中设置的protocol参数的值*
protocol:协议类型,可选类型有四种,分别为BIO(阻塞型IO),NIO,NIO2和APR。
1、 BIO:BIO(Blocking I/O),顾名思义,即阻塞式I/O操作,表示Tomcat使用的是传统的Java I/O操作(即java.io包及其子包)。Tomcat在默认情况下,是以bio模式运行的。遗憾的是,就一般而言,bio模式是三种运行模式中性能最低的一种。BIO配置采用默认即可。
protocol="HTTP/1.1"
2、 NIO: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)更好的并发运行性能。要让Tomcat以nio模式来运行也比较简单,我们只需要protocol类型修改为:

//NIO 
protocol="org.apache.coyote.http11.Http11NioProtocol" 
//NIO2 (异步非阻塞)
protocol="org.apache.coyote.http11.Http11Nio2Protocol"  

3、 APR:APR(Apache Portable Runtime/Apache可移植运行时),是Apache HTTP服务器的支持库。你可以简单地理解为:Tomcat将以JNI的形式调用 Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高 Tomcat对静态文件的处理性能。
与配置 NIO运行模式一样,也需要将对应的 Connector节点的 protocol属性值改为:
protocol="org.apache.coyote.http11.Http11AprProtocol"
***注:在tomcat6和7版本中,服务器会自动选择使用BIO或者APR模式处理网络请求,但需要在本地安装tomcat-native,tomcat的bin目录下自带tomcat-native.tar.gz包。


*关于这几种模式的性能*
并不是说 BIO的性能就一定不如 NIO,这几种类型 Connector之间并没有明显的性能区别,它们之间实现流程和原理不同,所以它们的选择是需要根据应用的类型来决定的。
BIO更适合处理简单流程,如程序处理较快可以立即返回结果。简单项目及应用可以采用BIO。
NIO更适合后台需要耗时完成请求的操作,如程序接到了请求后需要比较耗时的处理这已请求,所以无法立即返回结果,这样如果采用BIO就会占用一个连接,而使用NIO后就可以将此连接转让给其他请求,直至程序处理完成返回为止。NIO是tomcat8上的默认运行模式。
APR可以大大提升Tomcat对静态文件的处理性能,同时如果你使用了HTTPS方式传输的话,也可以提升SSL的处理性能。

*附:apr安装方法*
tomcat7上设置BIO方式即使用protocol="HTTP/1.1"时tomcat会自动搜索系统指定路径里是不是有apr的库文件,如果可以搜索到,则自动使用apr模式。默认tomcat安装时不安装apr库文件,apr需要自行安装并需要安装tomcat的bin目录下的tomcat-native包。
安装依赖库

因为apr模式本质是使用JNI技术调用操作系统IO接口,需要用到相关API的头文件

> yum install apr-devel
> yum install openssl-devel
> yum install gcc
> yum install make

gcc和make一般系统环境都会有,主要是安装apr-devel和openssl-devel(arp支持启用openssl的ssl功能,并且默认是开启的)

img

图片.png

依赖环境安装完之后安装apr的包(这里建议手动装,yum装之后后面安装tomcat-native包的时候会提示找不到apr的包,需要指定apr包的路径才行)
这里以apr-1.6.3为例

    > tar jxvf apr-1.6.3.tar.bz2
    > cd apr-1.6.3
    > ./configure --prefix=/usr/local/apr
    > make && make install

安装过apr之后还需要安装tomcat-native包

    > cd tomcat-dufg/bin
    > cd tomcat-native-1.1.31-src/jni/native
    > ./configure --with-apr=/usr/local/apr
    > make && make install

因为tomcat是需要搜索apr包的路径,所以和jdk一样apr也需要设置环境变量
*环境变量的三种设置方法*
1、设置LD_LIBRARY_PATH和LD_RUN_PATH环境变量,指向/usr/local/apr/lib目录,可配置到$HOME/.profile文件中

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
export LD_RUN_PATH=$LD_RUN_PATH:/usr/local/apr/lib

2、拷贝/usr/local/apr/lib目录下所有动态库到/usr/lib或/lib系统共享库搜索目录下即可。

    > copy /usr/local/apr/lib/libtcnative* /usr/lib/

3、编辑$TOMCAT_HOME/bin/catalina.sh文件,在虚拟机启动参数JAVA_OPTS中添加java.library.path参数,指定apr库的路径(推荐使用这种方法)

JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/apr/lib"

设置好之后重启tomcat,查看catalina.out日志输出

img

图片.png

出现"http-apr-8080"和"ajp-apr-8009",说明已经apr已经成功启用。
未安装时的输出是类似:INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: xxx/xxx这种。

作者:进击的胖达
链接:https://www.jianshu.com/p/24338493c82f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

优化内存

/bin/catalina.sh添加JAVA_OPTS参数
jdk1.7

JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=1024M -XX:PermSize=1024m -XX:MaxPermSize=1024m -XX:+DisableExplicitGC"

jdk1.8

1.8版本中已经没有PermSize、MaxPermSize

JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=1024M -XX:+DisableExplicitGC"

参数说明:
-Djava.awt.headless:没有设备、键盘或鼠标的模式。有关介绍:What is Headless mode in Java
-Dfile.encoding: 设置字符集
-server:jvm的server工作模式,对应的有client工作模式。使用“java -version”可以查看当前工作模式
-Xms512m:初始Heap大小,使用的最小内存
-Xmx1024m:Java heap最大值,使用的最大内存
-XX:NewSize=512m:表示新生代初始内存的大小,应该小于 -Xms的值
-XX:MaxNewSize=1024M:表示新生代可被分配的内存的最大上限,应该小于 -Xmx的值
-XX:PermSize=1024m:设定内存的永久保存区域(注:jdk1.8 was removed)
-XX:MaxPermSize=1024m:设定最大内存的永久保存区域(注:jdk1.8 was removed)
-XX:+DisableExplicitGC:自动将System.gc()调用转换成一个空操作,即应用中调用System.gc()会变成一个空操作

优化连接数

就算你把线程数调到很大,但是还是要看业务每个请求耗费的时间和资源

优化线程数

在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

使用线程池

在conf/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:线程优先级

优化运行模式(connector for protocol)

  1. BIO

    一个线程处理一个请求。缺点:并发量高时,线程数较多,浪费资源。Tomcat7或以下在Linux系统中默认使用这种方式。

配置conf/server.xml

```
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" enableLookups="false" redirectPort="8443" URIEncoding="UTF-8" />```
  1. NIO

    利用Java的异步IO处理,可以通过少量的线程处理大量的请求。Tomcat8在Linux系统中默认使用这种方式。Tomcat7必须修改Connector配置来启动(conf/server.xml配置文件)。

    配置conf/server.xml

    
    
3. apr

    apr=Apache Portable Runtime,从操作系统层面解决io阻塞问题。
    
    - 安装apr
    
        下载apr: http://www.linuxfromscratch.org/blfs/view/svn/general/apr.html
        
        ```shell
            tar xvf apr-1.5.2.tar.bz2
            cd apr-1.5.2
            ./configure --prefix=/usr --disable-static --with-installbuilddir=/usr/share/apr-1/build &&
            make
            make install
        ```
        > --disable-static: This switch prevents installation of static versions of the libraries
        
    - 安装tomcat-native

        进入tomcat/bin目录,比如:
    
        ```
        cd /home/vhs/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
        ```
        
    - 配置server.xml
        
        - 对tomcat设置环境变量,方法是在bin/catalina.sh文件中增加1行
        
            ` CATALINA_OPTS="-Djava.library.path=/usr/local/apr/lib" `
        - 修改conf/server.xml
        
          ```
          <Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" connectionTimeout="20000" enableLookups="false" redirectPort="8443" URIEncoding="UTF-8" />
        ```

        > tomcat启动遇到错误:failed to initialize the sslengine。
        > 解决办法:
        > 修改server.xml中Listener的className=“org.apache.catalina.core.AprLifecycleListener” 的参数SSLEngine为off。如下:`<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" />`
        
        
## 参考
   - [Tomcat7优化配置](http://www.linuxprobe.com/tomcat7-configure-optimize.html)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值