Tomcat并发量与其配置息息相关, 一般的机器几百的并发量足矣, 如果设置太高可能引发各种问题, 内存、网络等问题也能在高并发下暴露出来, 因此, 配置参数的设置非常重要.
1 Tomcat的3种运行模式
1.1 BIO - 同步阻塞IO模式
BIO, 同步阻塞IO, 性能低, 没有经过任何优化处理和支持.
服务器实现模式为一个连接一个线程, 即客户端有连接请求时服务器端就需要启动一个线程进行处理, 如果这个连接不做任何事情会造成不必要的线程开销, 当然可以通过 线程池 机制改善.
适用场景: BIO方式适用于连接数比较小且固定的架构, 这种方式对服务器资源要求比较高, 有并发局限, JDK1.4之前的唯一选择.
1.2 NIO - 同步非阻塞IO模式
是Java SE 1.4及后续版本提供的一种新的IO操作方式(即java.nio包及其子包). Java NIO是一个基于缓冲区、并能提供非阻塞IO操作的Java API, 因此NIO也被看成是non-blocking IO(非阻塞式IO)的缩写, 它拥有比传统BIO操作更好的并发性能.
服务器实现模式为一个请求一个线程, 即客户端发送的连接请求都会注册到多路复用器上, 多路复用器轮询到连接有IO请求时才启动一个线程进行处理.
适用场景: 适用于连接数较多且连接比较时间短(轻操作)的架构, 比如聊天服务器. 这种方式的并发性能局限于应用中, 编程比较复杂.
目前Tomcat 8.x默认运行在NIO模式下.
1.3 APR - 可移植运行时模式
APR(Apache Portable Runtime, Apache可移植运行时), 是Apache HTTP服务器的一个支持库, 它提供了一组映射到底层操作系统的API, 如果操作系统不支持特定功能, APR库将提供仿真. 因此开发人员可以使用APR使程序真正跨平台移植.
此模式的安装步骤比较繁琐, 但却从操作系统层面解决了异步IO的问题, 能大幅度提高应用性能.
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 namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
(2) 自定义线程池示例:
<Executor 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时, 将该请求转发到此端口.