Tomcat优化专题

Tomcat是我们经常使用的 servlet容器之一,甚至很多线上产品都使用 Tomcat充当服务器。而且优化后的Tomcat性能提升显著,总结了几方面进行分析优化。

一、配置优化

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

1.Connector 优化

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

  

1)port:代表Tomcat监听端口,也就是网站的访问端口,默认为8080,可以根据需要改成其他。

2)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" 

3)maxThreads:由该连接器创建的处理请求线程的最大数目,也就是可以处理的同时请求的最大数目。如果未配置默认值为200。 maxThreads是一个重要的配置属性,maxThreads配置的合理直接影响了Tomcat的相关性能,需要重点关注。maxThreads并不是配置的越大越好,事实上即使配置成999999也是没有用的,因为这个最大值是受操作系统及相关硬件所制约的,并且最大值并不一定是最优值,所以我们追寻的应该是最优值而不是最大值。

QPS(Query Per Second):每秒查询率QPS,(服务器每秒能处理的流量)对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。我们常常使用QPS值来衡量一个服务器的性能

一个系统吞吐量(所谓吞吐量这里可以理解为每秒能处理请求的次数)通常由QPS、并发数两个因素决定,每套系统的这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降,原因是系统超负荷工作,上下文切换、内存等等其它消耗导致系统性能下降。

  • 通过线上系统不断使用和用户的不断增长来进行性能测试,观察QPS,响应时间,这种方式会在爆发式增长时系统崩溃,如双12等。
  • 根据公式计算,服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量,这种方式有时会被误导,因为某些系统处理环节可能会耗时比较长,从而影响公式的结果。
  • 单、多用户压力测试,查看CPU的消耗,然后直接乘以百分比,再进行压测,一般这个值的附近应该就是最佳线程数量,这种方式理想场景比较适用,实际情况会比这个复杂的多。
  • 根据系统的自身情况调整,如硬件限制,系统限制,程序处理能力限制等。
  • 定期修改为不同的maxThreads值,看服务器响应结果及用户反应。

QPS和线程数的关系

  • 在最佳线程数量之前,QPS和线程是互相递增的关系,线程数量到了最佳线程之后,QPS持平,不在上升,甚至略有下降,同时相应时间持续上升。
  • 同一个系统而言,支持的线程数越多(最佳线程数越多而不是配置的线程数越多),QPS越高。

QPS和响应时间的关系

  • 对于一般的web系统,响应时间一般有CPU执行时间+IO等待时间组成。
  • CPU的执行时间减少,对QPS有实质的提升,IO时间的减少,对QPS提升不明显。如果要想明显提升QPS,优化系统的时候要着重优化CPU消耗大户。

所以想要找出 maxThreads的最优值可并不容易,没有最好只有更好,更好的值只能通过时间来显现,如果你不想考虑那么多,一般情况下设置成1000即可。

Tomcat优化专题_第1张图片
测试

并不一定某种protocol就一定性能出色,因为Tomcat中的这个测试项目只有一个index.jsp页面,在较少线程数访问情况下BIO反应最快,而当线程数达到1000时NIO2性能最出色,而APR中规中矩,虽然这种测试的局限性很大,但也可以反映出:想要找出适合的配置及最佳性能需要结合实际,不断的测试与改进,最终才能达到一个相对稳定的性能,虽然此时的性能未必是最佳的,但却是能应对绝大多数情况的。

BIO更适合处理简单流程,如程序处理较快可以立即返回结果。简单项目及应用可以采用BIO。

NIO更适合后台需要耗时完成请求的操作,如程序接到了请求后需要比较耗时的处理这已请求,所以无法立即返回结果,这样如果采用BIO就会占用一个连接,而使用NIO后就可以将此连接转让给其他请求,直至程序处理完成返回为止。

APR可以大大提升Tomcat对静态文件的处理性能,同时如果你使用了HTTPS方式传输的话,也可以提升SSL的处理性能。

2.线程池优化

Executor代表了一个线程池,可以在Tomcat组件之间共享。使用线程池的好处在于减少了创建销毁线程的相关消耗,而且可以提高线程的使用效率。要想使用线程池,首先需要在 Service标签中配置 Executor,如下:

  
      
  ....  

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中指定:

【Tomcat优化详细教程】

你可能感兴趣的:(Tomcat优化专题)