Tomcat 8.0的并发优化 - 优化server.xml的配置

Tomcat并发量与其配置息息相关, 通常的机器几百的并发量足矣, 若是设置过高可能引起各类问题, 内存、网络等问题也能在高并发下暴露出来, 所以, 配置参数的设置很是重要.javascript

1 Tomcat的3种运行模式

1.1 BIO - 同步阻塞IO模式

BIO, 同步阻塞IO, 性能低, 没有通过任何优化处理和支持.css

服务器实现模式为一个链接一个线程, 即客户端有链接请求时服务器端就须要启动一个线程进行处理, 若是这个链接不作任何事情会形成没必要要的线程开销, 固然能够经过 线程池 机制改善.html

适用场景: BIO方式适用于链接数比较小且固定的架构, 这种方式对服务器资源要求比较高, 有并发局限, JDK1.4以前的惟一选择.java

1.2 NIO - 同步非阻塞IO模式

是Java SE 1.4及后续版本提供的一种新的IO操做方式(即java.nio包及其子包). Java NIO是一个基于缓冲区、并能提供非阻塞IO操做的Java API, 所以NIO也被当作是non-blocking IO(非阻塞式IO)的缩写, 它拥有比传统BIO操做更好的并发性能.web

服务器实现模式为一个请求一个线程, 即客户端发送的链接请求都会注册到多路复用器上, 多路复用器轮询到链接有IO请求时才启动一个线程进行处理.shell

适用场景: 适用于链接数较多且链接比较时间短(轻操做)的架构, 好比聊天服务器. 这种方式的并发性能局限于应用中, 编程比较复杂.apache

目前Tomcat 8.x默认运行在NIO模式下.编程

1.3 APR - 可移植运行时模式

APR(Apache Portable Runtime, Apache可移植运行时), 是Apache HTTP服务器的一个支持库, 它提供了一组映射到底层操做系统的API, 若是操做系统不支持特定功能, APR库将提供仿真. 所以开发人员可使用APR使程序真正跨平台移植.浏览器

此模式的安装步骤比较繁琐, 但却从操做系统层面解决了异步IO的问题, 能大幅度提升应用性能.tomcat

APR的本质是使用 JNI 技术调用操做系统底层的IO接口, 因此须要提早安装必要的依赖, 具体方式后续给出.

2 Tomcat的并发配置(配置Connector)

Tomcat的Connector是其接收HTTP请求的关键模块, 能够经过它来指定IO处理模式, 指定处理该Connector接收到的请求的线程数, 以及其余经常使用的HTTP策略.

配置路径: 在 ${TOMCAT_HOME}/conf/server.xml 文件的节点中进行配置.

2.1 使用线程池处理请求

使用线程池, 经过较少的线程资源来处理更多的请求, 从而提升Tomcat的请求处理能力.

前提: 要提早配置至少一个线程池来处理请求, 配置文件为${TOMCAT_HOME}/conf/server.xml.

其中Executor与Connector同级, 多个Connector可使用同一个线程池来处理请求.

(1) 参考默认链接池配置:

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>

(2) 自定义线程池示例:

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="200" minSpareThreads="10" maxIdleTime="600000" prestartminSpareThreads="true" maxQueueSize="100" /> 

(3) 线程池参数说明:

name: 线程池名称.
namePrefix: 建立的每一个线程的名称前缀, 单独的线程名称为 namePrefix + threadNumber.
maxThreads: 线程池中最大并发线程数, 默认值为200, 通常建议设置400~ 800 , 要根据服务器配置和业务需求而定.
minSpareThreads: 最小活跃线程数, 也就是核心线程数, 不会被销毁, 会一直存在.
prestartminSpareThreads: 是否在启动程序时就生成minSpareThreads个线程, 默认为false, 即不启动. 若不设置为true, 则minSpareThreads的设置就不起做用了.
maxIdleTime: 线程最大空闲时间, 超过该时间后, 空闲线程会被销毁, 默认值为6000, 单位为毫秒.
maxQueueSize: 最大的等待队列数, 超过则拒绝请求. 默认值为int类型的最大值(Integer.MAX_VALUE), 等同于无限大. 通常不做修改, 避免发生部分请求未能被处理的状况.
threadPriority: 线程池中线程的优先级, 默认值为5, 取值范围: 1 ~ 10.
className:线程池的实现类, 未指定状况下, 默认实现类为 org.apache.catalina.core.StandardThreadExecutor. 要自定义线程池就须要实现 org.apache.catalina.Executor 接口.

2.2 在Connector中使用线程池

Connector是Tomcat接收请求的入口, 每一个Connector都有本身专属的监听端口.

<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

(1) Connector的参数说明:

redirectPort="8443" # 基于SSL的端口, 在须要基于安全通道的场合, 好比当客户端的请求协议是HTTPS时, 将该请求转发到此端口.

minSpareThreads="25" # Tomcat链接器的最小空闲Socket线程数, 默认值为25. 若是当前没有空闲线程, 且没有超过maxThreads, 将一次性建立的空闲线程数量. Tomcat初始化时建立的线程数量也是此值.

maxSpareThreads="75" # 最大空闲线程数, 一旦建立的线程超过此值, Tomcat就会关闭再也不须要的Socket线程, 默认值为50. 线程数能够大体用 "同时在线用户数、用户每秒操做次数、系统平均操做时间" 来计算.

keepAliveTimeout="6000" # 下次请求到来以前, Tomcat保持该链接6000ms.

maxKeepAliveRequests="10" # 该链接最大支持的请求数, 超过该请求数的链接也将被关闭(此时就会返回一个Connection: close头给客户端). 1表示禁用长链接, -1表示不限制链接个数, 默认为100, 通常设置在100~200之间.

acceptorThreadCount="1" # 用于接收链接的线程的数量, 默认值是1. 通常若是服务器是多核CPU时, 须要改配置为 2.

enableLookups="false" # 是否支持反查域名(即DNS解析), 默认为true. 为提升处理能力, 应设置为false.

disableUploadTimeout="true" # 上传时是否启用超时机制, 若为true, 则禁用上传超时.

connectionTimeout="20000" # 网络链接超时时间, 默认值为20000ms, 设置为0表示永不超时 —— 存在隐患. 一般可设置为30000ms.

URIEncoding="UTF-8" # 指定Tomcat容器的URL编码格式.

maxHttpHeaderSize="8192" # HTTP请求头信息的最大程度, 超过此长度的部分不予处理. 通常设置为8K便可.

maxPostSize="10485760" # 指定POST请求的内容大小, 单位为Byte, 默认大小为2097152(2MB), 10485760为10M. 若是要禁用限制, 可设置为-1.

compression="on" # 打开传输时压缩功能.

compressionMinSize="10240" # 启用压缩的输出内容大小, 默认为2048, 即2KB.

noCompressionUserAgents="gozilla, traviata" # 设置不启用压缩的浏览器

compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" # 压缩的资源类型

(2) 补充说明:

① Tomcat 的压缩是在客户端请求服务器对应资源后, 从服务器端将资源文件压缩, 再输出到客户端, 由客户端的浏览器负责解压缩并浏览. 相对于普通的浏览过程(如浏览HTML、CSS、Javascript和Text), 它能够节省40%左右的流量. 更为重要的是, 它也能够对动态生成的网页(包括CGI、PHP、JSP、ASP、Servlet、SHTML等)进行压缩.

② 须要注意的是, 压缩会增长Tomcat的负担, 最好采用 Nginx + Tomcat 或 Apache + Tomcat 方式, 将压缩交由 Nginx / Apache 去完成. 在server.xml的节点配置(还没有验证使用):

  • <Service name="Catalina" /> --- 处理全部直接由Tomcat服务器接收的web客户请求.
  • <Service name="Apache" /> --- 处理全部由Apahce服务器转发过来的Web客户请求.
  • <Service name="Nginx" /> --- 处理全部由Nginx服务器转发过来的Web客户端请求.

2.2 使用NIO模式处理请求

(1) 默认配置 - BlockingIO模型:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

(2) 关于NIO的说明:

  • 每一个Web客户端请求对服务器端来讲就是一个单独的线程, 客户端请求数量增多, 服务器端的处理线程数量也将增长, 对CPU而言, 将会在线程切换上消耗更多的时间. 而NIO则是使用单线程(单个CPU)或只使用少许的多线程(多CPU)来接受Socket, 而由线程池来处理堵塞在 Pipe 或 Queue 中的请求. 这样的话, 只要OS能够接受TCP链接, Web服务器就能够处理该请求 -- 大大提升了Web服务器的伸缩性.
  • Tomcat 8 下使用 NIO2, 即 org.apache.coyote.http11.Http11Nio2Protocol 更优.
  • Tomcat 六、7 下使用 NIO, 即 org.apache.coyote.http11.Http11NioProtocol 更优.

(3) NIO模型配置:

<Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" connectionTimeout="20000" redirectPort="8443" maxPostSize="10485760" acceptorThreadCount="2" />

(4) 参数说明:

executor="..."  # 链接器使用的线程池名称. 
port="..."      # 链接端口, URL中指定此端口进行访问.  
protocol="..."  # 链接器使用的请求处理模式.  
redirectPort="8443"   # 基于SSL的端口, 在须要基于安全通道的场合, 好比当客户端的请求协议是HTTPS时, 将该请求转发到此8443端口.

2.3 使用APR模式处理请求

能够简单地将APR模式理解为,Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态连接库, 进行文件读取或网络传输操做, 从而大大地提升Tomcat对静态文件的处理性能.

APR是Tomcat上运行高并发应用的首选模式, 同时若是使用HTTPS方式传输, 也能够提高SSL的处理性能.

前面已经提到, APR模式会调用操做系统底层的IO接口, 因此须要安装必要的依赖.

(1) 安装OpenSSL:

安装命令以下:

yum -y install openssl-devel

(2) 安装APR组件:

  • 第一步: 下载apr与apr-util安装包:
    下载地址: http://apr.apache.org/download.cgi. 这里下载apr-1.6.3.tar.gzapr-util-1.6.1.tar.gz, 而后将安装包上传至服务器, 这里上传至 /usr/local 目录下.

  • 第二步: 安装apr:

    cd /usr/local
    tar -zxf apr-1.6.3.tar.gz
    cd apr-1.6.3
    # 配置安装路径 ./configure --prefix=/usr/local/apr # 编译安装 make make install
  • 第三步: 安装apr-util:

    cd /usr/local
    tar -zxf apr-util-1.6.1.tar.gz
    cd apr-util-1.6.1
    # 配置安装路径 ./configure --prefix=/usr/local/apr-util--with-apr=/usr/local/apr # 编译安装 make make install

    错误提示:

    可能出现gcc依赖没有安装的错误, 可经过 yum install gcc 命令安装.

    若是make过程当中出错, 解决错误后从新安装前须要执行清理: make clean, 而后再次尝试make及make install过程.

    若是抛出 xml/apr_xml.c:35:19: error: expat.h: No such file or directory, 说明缺乏了expat库, 可执行下属命令安装: yum install expat-devel.

  • 第四步: 配置环境变量:

    上面安装完后设置下环境变量:
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib

    或者, 将/usr/local/apr/lib包路径添加到/etc/ld.so.conf文件中:
    echo "/usr/local/apr/lib" >> /etc/ld.so.conf

(3) 安装tomcat-native组件:

tomcat-native组件能够看做是Tomcat与APR交互的中间环节.

  • 第一步: 下载并解压native安装包:

    前往 ${TOMCAT_HOME}/bin 目录下找到tomcat-native.tar.gz, 也可前往官网(http://tomcat.apache.org/download-native.cgi)下载其余版本, 推荐使用Tomcat自带的版本, 兼容性有更大保证.

    解压tomcat-native组件并安装, 或上传本身下载的native组件至服务器后, 再执行下述过程:

    cd /usr/local/tomcat/bin/
     tar -zxf tomcat-native.tar.gz
     cd tomcat-native-1.2.14-src/native/

    注意: 1.1.x版本中的目录是tomcat-native-1.1.x-src/jni/native.

  • 第二步: 安装组件:

    # 配置安装参数, 其中java-home可以使用默认环境变量中的配置 ./configure --with-apr=/usr/local/apr --with-ssl=yes make make install

(4) Tomcat整合APR:

  • 第一步: 修改启动脚本catalina.sh:
    ${TOMCAT_HOME}/bin/catalina.sh 文件的 cygwin=false 前(110行左右)加入下述启动参数:

    JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/apr/lib"
  • 第二步: 修改容器配置文件server.xml:

    查看 ${TOMCAT_HOME}/conf/server.xml 文件, 确保以下监听器没有被注释掉:

    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  • 修改Connector选项:

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" SSLEnabled="true" > </Connector>

(5) 验证配置是否成功:

启动Tomcat, 在 ${TOMCAT_HOME}/logs/catalina.out 文件中查看日志信息:

  • 若是出现下述内容, 说明APR组件安装不成功:

    Sep 14, 2018 19:11:20 PM org.apache.catalina.core.AprLifecycleListener init 
    INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path:...
  • 若是出现下述内容, 说明APR组件安装成功:

    Sep 14, 2018 19:19:47 PM org.apache.catalina.core.AprLifecycleListener init
    INFO: Loaded APR based Apache Tomcat Native library 1.1.27 using APR version 1.6.3.
    Sep 14, 2018 19:19:47 PM org.apache.catalina.core.AprLifecycleListener init
    INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
    Sep 14, 2018 19:19:47 PM org.apache.catalina.core.AprLifecycleListener initializeSSL
    INFO: OpenSSL successfully initialized (OpenSSL 1.0.1e-fips 11 Feb 2013)
    Sep 14, 2018 19:19:47 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler ["http-apr-8080"]
    Sep 14, 2018 19:19:47 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler ["ajp-apr-8009"]
  • Tomcat经过APR模式成功启动:

    Sep 14, 2018 19:19:56 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["http-apr-8986"]
    Sep 14, 2018 19:19:56 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["ajp-apr-8915"]
    Sep 14, 2018 19:19:56 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 9421 ms

3 配置AJP链接器

AJP(Apache JServer Protocol)是为 Tomcat 与 HTTP 服务器之间通讯而定制的协议, 能提供较高的通讯速度和效率.

与案例说明: AJP v13 协议是面向包的, Web服务器和Servlet容器经过TCP链接来交互, 为了节省 建立Socket的昂贵代价, Web服务器会尝试维护一个永久的TCP链接到Servlet容器, 并在多个请求与响应周期过程内重用该TCP链接.

若是使用Apache架构, 就要用AJP链接器, 当Apache接收到动态网页请求时, 经过在配置中指定的端口号将请求发送给在此端口号上监听的AJP链接器组件.

若是不使用Tomcat + Apache, 而是用其余架构, 如Tomcat + Nginx, 就须要注销掉该链接器.

<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
相关文章
相关标签/搜索