Tomcat 性能优化

Tomcat 简单介绍

Sun 公司创建了第一个 Servlet 容器,即 Java Web Server,但 JWS 只是为了演示 Servlet 的相应功能,所以其性能很不稳定。与此同时,apache 基金会组织 (ASF) 创建了 JServ 项目,一个能够与 apache 整合起来的 servlet 容器。

1999 年,Sun 公司把 JWS 捐给了 ASF,于是两个项目合二为一,即今天 Tomcat 的前身。第一个 tomcat 版本是 Tomcat 3.x 系列,而发布于 2001 年 Tomcat4.0 则是在此前基础上进行了重新设计和实现,其代码项目被命名为 Catalina。

Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选。

版本介绍:现在版本更新到 Apache Tomcat 8.x,但是 Apache Tomcat 7.x 是目前开发的焦点。Apache Tomcat 7.x 它在汲取了 Tomcat 6.0.x 优点的基础上,实现了对于 Servlet 3.0、JSP 2.2 和 EL 2.2 等特性的支持。

除此以外的改进列表如下:

  • Web 应用内存溢出侦测和预防
  • 增强了管理程序和服务器管理程序的安全性
  • 一般 CSRF 保护
  • 支持 web 应用中的外部内容的直接引用
  • 重构 (connectors, lifecycle) 及很多核心代码的全面梳理

tomcat 运行模式介绍

Tomcat Connector(Tomcat 连接器) 有 bio、nio、apr 三种运行模式,那么这三种运行模式有什么区别呢,我们又如何修改 Tomcat Connector 的运行模式来提高 Tomcat 的运行性能呢?

bio 模式

bio(blocking I/O),顾名思义,即阻塞式 I/O 操作,表示 Tomcat 使用的是传统的 Java I/O 操作 (即 java.io 包及其子包)。Tomcat 在默认情况下,就是以 bio 模式运行的。遗憾的是,就一般而言,bio 模式是三种运行模式中性能最低的一种。我们可以通过 Tomcat Manager 来查看服务器的当前状态。

  1. [root@web conf]# cd /data/node1/conf/tomcat-users.xml
  2. [root@web conf]# vim tomcat-users.xml #添加进去两行代码,也就是新创建一个账号和密码。
<role rolename="manager-gui"/>
 <user username="tomcat" password="tomcat" roles="manager-gui"/>
  1. 添加之后,然后保存退出此文件。想让配置文件生效,需要重启下 tomcat。
  2. [root@web conf]# /data/node1/bin/shutdown.sh [root@web conf]# /data/node1/bin/startup.sh

点击 Server Status 查看下状态:

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 模式来运行也比较简单,我们只需要在 Tomcat 安装目录 / conf/server.xml 文件中将如下配置:

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

其中的 protocol 属性值改为 org.apache.coyote.http11.Http11NioProtocol 即可:

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"connectionTimeout="20000"redirectPort="8443" />

此时,我们就可以在 Tomcat Manager 中看到当前服务器状态页面的 HTTP 协议的 Connector 运行模式已经从 http-bio-8080 变成了 http-nio-8080。

apr 模式

apr(Apache Portable Runtime/Apache 可移植运行时),是 Apache HTTP 服务器的支持库。你可以简单地理解为,Tomcat 将以 JNI 的形式调用 Apache HTTP 服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高 Tomcat 对静态文件的处理性能。

Tomcat apr 也是在 Tomcat 上运行高并发应用的首选模式。如果我们的 Tomcat 不是在 apr 模式下运行,在启动 Tomcat 的时候,我们可以在日志信息中看到类似如下信息:

org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: xxx/xxx(这里是路径信息)

Tomcat apr 运行模式的配置是三种运行模式之中相对比较麻烦的一种。据官方文档所述,Tomcat apr 需要以下三个组件的支持:

  • APR library[APR 库] JNI wrappers for APR used by Tomcat (libtcnative)[简单地说,如果是在 Windows 操作系统上,就是一个名为 tcnative-1.dll 的动态链接库文件]
  • OpenSSL libraries[OpenSSL 库] 此外,与配置 nio 运行模式一样,也需要将对应的 Connector 节点的 protocol 属性值改为org.apache.coyote.http11.Http11AprProtocol。 不过,上述繁琐的操作都是 Tomcat 7.0.30 之前的版本才需要这样配置,从 Tomcat 7.0.30 版本开始,Tomcat 已经自带了 tcnative-1.dll 等文件,并且默认就是在 Tomcat apr 模式下运行,因此我们只需要下载最新版本的 Tomcat 直接使用即可。

默认情况下是 bio 模式,介绍下怎么更换成 apr 模式:

[root@web]#yum install -y apr apr-util apr-devel[root@web]# cd /data/node1/bin[root@web bin]# tar -zxvf tomcat-native.tar.gz[root@web bin]# cd tomcat-native-1.1.32-src/jni/native/[root@web native]# ./configure --with-apr=/usr/bin/apr-1-config --with-ssl=/usr/include/openssl/[root@web native]# make && make installtomcat和apr库整合,需要修改shell脚本文件catalina.sh
[root@web node1]# vim /data/node1/bin/catalina.sh +99JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+DisableExplicitGC"  cygwin=falsedarwin=falseCATALINA_OPTS="-Djava.library.path=/usr/local/apr/lib"os400=false

保存退出,重启 tomcat。看 tomcat 启动输出日志信息:

信息: Deploying web application directory /data/node1/webapps/host-manager
四月 10, 2018 16:42:19 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deployment of web application directory /data/node1/webapps/host-manager has finished in 156 ms
四月 10, 2018 16:42:19 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory /data/node1/webapps/examples
四月 10, 2018 16:42:19 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deployment of web application directory /data/node1/webapps/examples has finished in 1,490 ms
四月 10, 2018 16:42:19 下午 org.apache.coyote.AbstractProtocol start信息: Starting ProtocolHandler ["http-apr-8080"]
四月 10, 2018 16:42:19 下午 org.apache.catalina.startup.Catalina start信息: Server startup in 25191 ms

出现了 ["http-apr-8080"] 字段,说明现在 tomcat 已经是 apr 模式。

Tomcat 安全和性能优化

内存优化

修改内存等 JVM 相关配置

Linux 下修改 TOMCAT_HOME/bin/catalina.sh,在其中加入,可以放在 CLASSPATH = 下面:

JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m"  

windows 下修改 TOMCAT_HOME/bin/catalina.bat,在其中加入,可以放在 set CLASSPATH = 下面:

set JAVA_OPTS=-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m  

这些参数在我们学习 JVM 部分文章时已经都认识过了,不过这里还是简单介绍下:

-server:启用 JDK的 server 版本;-Xms:Java虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能;-Xmx:Java虚拟机可使用堆的最大内存;-XX:PermSize:Java虚拟机永久代大小;-XX:MaxPermSize:Java虚拟机永久代大小最大值;

除了这些参数外您还可以根据具体需要配置其他参数,参数的配置可以参考 JVM 参数的配置。

配置优化

我们知道 TOMCAT_HOME/conf/server.xml 可以配置端口,虚拟路径等等 Tomcat 相关主要配置。

1) Connector 优化

Connector 是连接器,负责接收客户的请求,以及向客户端回送响应的消息。所以 Connector 的优化是重要部分。默认情况下 Tomcat 只支持 200 线程访问,超过这个数量的连接将被等待甚至超时放弃,所以我们需要提高这方面的处理能力。

修改这部分配置需要修改 TOMCAT_HOME/conf/server.xml,打开 server.xml 找到 Connector 标签项,默认配置如下:

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

其中 port 代表服务接口;protocol 代表协议类型;connectionTimeout 代表连接超时时间,单位为毫秒;redirectPort 代表安全通信(https)转发端口,一般配置成 443。

可以看到除了这几个基本配置外并无特殊功能,所以我们需要对 Connector 进行扩展。

其中 Connector 支持参数属性可以参考 Tomcat 官方网站(https://tomcat.apache.org/tomcat-8.0-doc/config/http.html ),非常多,所以本文就只介绍些常用的。

我们将 Connector 配置修改为如下:

    <Connector port="8080"   
              protocol="HTTP/1.1"   
          maxThreads="1000"   
              minSpareThreads="100"   
          acceptCount="1000"  
              maxConnections="1000"  
          connectionTimeout="20000"   
          maxHttpHeaderSize="8192"  
              tcpNoDelay="true"  
              redirectPort="8443"  
      enableLookups="false"  
              URIEncoding="UTF-8" />  
  • port:代表 Tomcat 监听端口,也就是网站的访问端口,默认为 8080,可以根据需要改成其他。 -protocol:协议类型,可选类型有四种,分别为 BIO(阻塞型 IO),NIO,NIO2 和 APR。

BIO:BIO(Blocking I/O),顾名思义,即阻塞式 I/O 操作,表示 Tomcat 使用的是传统的 Java I/O 操作 (即 java.io 包及其子包)。Tomcat 在默认情况下,是以 bio 模式运行的。遗憾的是,就一般而言,bio 模式是三种运行模式中性能最低的一种。BIO 配置采用默认即可。 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"  
 即可。
2) 线程池

Executor 代表了一个线程池,可以在 Tomcat 组件之间共享。使用线程池的好处在于减少了创建销毁线程的相关消耗,而且可以提高线程的使用效率。

要想使用线程池,首先需要在 Service 标签中配置 Executor,如下:

<Service name="Catalina">  <Executor name="tomcatThreadPool"   
       namePrefix="catalina-exec-"   
      maxThreads="1000"   
        minSpareThreads="100"  
        maxIdleTime="60000"  
       maxQueueSize="Integer.MAX_VALUE"  
       prestartminSpareThreads="false"  
        threadPriority="5"  
        className="org.apache.catalina.core.StandardThreadExecutor"/>   ....    
其中,name:线程池名称,用于 Connector中指定。namePrefix:所创建的每个线程的名称前缀,一个单独的线程名称为 namePrefix+threadNumber。maxThreads:池中最大线程数。minSpareThreads:活跃线程数,也就是核心池线程数,这些线程不会被销毁,会一直存在。maxIdleTime:线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为6000(1分钟),单位毫秒。maxQueueSize:在被执行前最大线程排队数目,默认为Int的最大值,也就是广义的无限。除非特殊情况,这个值不需要更改,否则会有请求不会被处理的情况发生。prestartminSpareThreads:启动线程池时是否启动 minSpareThreads部分线程。默认值为false,即不启动。threadPriority:线程池中线程优先级,默认值为5,值从1到10。className:线程池实现类,未指定情况下,默认实现类为org.apache.catalina.core.StandardThreadExecutor。如果想使用自定义线程池首先需要实现 org.apache.catalina.Executor接口。

线程池配置完成后需要在 Connector 中指定:

<Connector executor="tomcatThreadPool"  ...  
3) Listener 配置

另一个影响 Tomcat 性能的因素是内存泄露。Server 标签中可以配置多个 Listener,其中 JreMemoryLeakPreventionListener 是用来预防 JRE 内存泄漏。此 Listener 只需在 Server 标签中配置即可,默认情况下无需配置,已经添加在 Server 中。

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />  

缓存优化

参数说明

  compression 打开压缩功能 
  compressionMinSize 启用压缩的输出内容大小,这里面默认为2KB 
  compressableMimeType 压缩类型 
  connectionTimeout 定义建立客户连接超时的时间. 如果为 -1, 表示不限制建立客户连接的时间
<Connector port="9027"  ...........
  compression="on"  compressionMinSize="2048"connectionTimeout="20000"compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"................
  />

大家通过以上我们队 tomcat 的有效配置,包括 (从内存,运行模式、并发、缓存 4 个方面) 优化。能让自己的项目稳定的服务于客户,达到我们理想的运行效果。

原文发布于微信公众号 - GitChat精品课(CSDN_Tech)

原文发表时间:2018-05-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java技术栈

干货 | Tomcat 连接数与线程池详解

在使用tomcat时,经常会遇到连接数、线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector)。

2064
来自专栏云原生架构实践

JHipster生成单体架构的应用示例

因为这个例子是生成单体架构的应用,所以这里选择默认选项Monolithic application,也就是单体架构的应用。

1.1K2
来自专栏nice_每一天

理解 IntelliJ IDEA 的项目配置和Web部署

IDEA 中最重要的各种设置项,就是这个 Project Structre 了,关乎你的项目运行,缺胳膊少腿都不行。最近公司正好也是用之前自己比较熟悉的IDEA...

5372
来自专栏小狼的世界

在Centos 5.2下编译安装LAMP

首先使用Virtualbox安装一台CentOS 5.2的虚拟机,网络连接采用 Host-only Adapter,这样主客机之间可以互相访问,但是客机不能够上...

1082
来自专栏杂烩

sqoop2安装 原

折腾了一天,最后才发现sqoop2暂时只支持mysql到hdfs或者hdfs到mysql,不支持hive或者hbase,无语啊。不过这里还是记下sqoop2的安...

1205
来自专栏蓝天

ZooKeeper-3.4.6分布式安装指南

介绍ZooKeeper-3.4.6版本的分布式安装,力求细致,提供精确的安装指导。本文的安装环境是64位的SuSE 10.1 Linux,也适用于ZooKe...

1511
来自专栏你不就像风一样

Gradle构建工具简明教程(IDEA篇)

GRADLE_USER_HOME 的作用是让其他程序检测到本地.gradle文件夹的位置,

1851
来自专栏WindCoder

tomcat基础小结

bin:可执行文件,包含启动脚本 conf:配置文件 lib:tomcat的依赖库 logs:日志 temp:临时文件 webapp:默认的应用部署目...

991
来自专栏不止是前端

Vue:前后端数据联调

4209
来自专栏JMCui

Hybris 6.4 + Jrebel

Jrebel官网参考地址:https://manuals.zeroturnaround.com/jrebel/standalone/hybris.html Wi...

3306

扫码关注云+社区

领取腾讯云代金券