阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

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

150次阅读
没有评论

共计 8421 个字符,预计需要花费 22 分钟才能阅读完成。

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 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 6、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.gz 和 apr-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″ />  –>

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计8421字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中