《java—Tomcat高性能调优方案详解》要点:
本文介绍了java—Tomcat高性能调优方案详解,希望对您有用。如果有疑问,可以联系我们。
一丶原理
概要
Tomcat大致分为两个部分,Connector组件及Container组件.Connector组件负责控制入口连接,并关联着一个Executor.Container负责Servlet容器的实现,Executor负责具体的业务逻辑,如Servlet的执行.一个哀求到达服务器后,经过以下关键几步,参见图1:
OS与客户端握手并建立连接,并将建立的连接放入完成队列,不妨叫Acceptor Queque.这个队列的长度便是Connector的acceptCount值.
Tomcat中的acceptor线程,赓续从Acceptor Queque中获取连接.
Acceptor Queque队列中没有连接,Acceptor线程继续监视
Acceptor Queque队列中有新连接,Acceptor线程将检查当前的连接数是否跨越了maxConnections
如果超过maxConnections,则阻塞.直到连接数小于maxConnections,acceptor线程将哀求交由Executor负责执行.
Executor将分配worker线程来处理哀求数据的读取,处理(servlet的执行)以及响应.
参数
acceptCount
acceptCount 实际上是Bind Socket时候传递的backlog值,在linux平台下含义是已经建立连接还没有被应用获取的连接队列最大长度.此时,如果哀求个数达到了acceptCount,新进的哀求将抛出refuse connection.
maxConnections:
顾名思义,即Tomcat允许的同时存在的最大连接数.默认BIO模式下,这个数值等于maxThreads,即最大线程数.超过这个值后,acceptor线程被Block.新进入的连接将由acceptCount控制.当当前连接数小于这个数值时,acceptor线程被唤醒,新的连接能力进入Executor执行.
executor
JDK缺省的ThreadPoolExecutor的逻辑是:
如果线程数小于coreThreadSize, 优先建立新线程.
如果线程数大于coreThreadSize小于maxThreadSize,将哀求入队列等待.
队列满的时候,才扩充线程数直到maxThreadSize.
当队列满,同时线程数大于maxThreadSize时,抛出异常.
Tomcat对JDK的ThreadPoolExecutor默认行为做了修改.使用承继自无界队列的LinkedBlockingQueue的TaskQueue,并改写了其入队策略,是的tomcat的Executor具有以下特性.
只要线程不足,而且小于maxThreads, 优先建立新线程.而不是超过coreSize,先入队列.
Executor如果发生reject,则将任务继续参加队列.而默认队列的size是Integer.MAX_VALUE,因此不会Reject.
在配置中,Executor可以单独配置,并被整个Tomcat共享.如果不配置,则Connector组件将使用本身默认的实现.
maxThreads
Worker线程的最大值.每当一个哀求进来时,如果当前线程数小于这个值,则创建新的线程.如果大于这个值,则查找空闲线程.如果没有空闲线程,则被Block住.
protocol
可以有三个取值,BIO,NIO, APR.BIO使用阻塞Socket实现,一个连接一个线程的模型.NIO使用的时候非阻塞socket实现.APR是apache实现的一个夸平台的库,也是apache http服务以来的核心网络组件.
以上介绍的几个参数之间存在着微妙的关系.一方面可以限制过多的哀求来保护系统资源,另一方面提供缓冲队列来提高系统的吞吐量.在低并发条件下,默认值基本满足要求.而在高并发的情况下,就需要根据具体的计算资源,评估以上参数的设置,来充分调动计算资源.
二丶应用
默认值的效果
背景中的case除了使用异步Servlet,后端依赖的服务也全部采用异步调用.即在tomcat的woker线程中,没有任何阻塞,只是做纯粹的本地CPU计算, 为了模拟服务失败的情况,后端服务被mock住,并随机sleep 0~3s.初次使用了tomcat的默认设置(具体值参见后表中第1条).由于后端woker线程很快(发送异步哀求后就结束了),一个线程在1s内可以处理多于一个的哀求.此时,如果maxConnections等于maxThreads 的值,很显然不能完全激活全部工作线程.如图2:
300个线程,只能达到140左右的吞吐量,tomcat worker线程只有17个上下,平均响应时间已经2s多了(理论上正常平均应该1.5s),继续增加线程,返回异常,说明已经达到了极限值.可以理解为,在异步情况下,20个worker线程每秒就能处理140个哀求.
maxConnection的应用
为了将worker线程打满,同时对后端的异步服务有足够的信心,逐步将maxConnection调整到2000,使用2000个并发打压.此时200个worker线程都工作了.吞吐量已经达到了1308(如图3),此时应该是应用最大吞吐量了.至此,初步达到了预期效果.
NIO Connector的应用
还有个NIO Connector,看到名字便是支持异步的IO了,在其它参数不变的情况下,换成NIO Connector.如图4所示,在吞吐量基本不变的情况下,线程数基本减少了一半.
在启用NIO Connector,servlet及后端调用不异步的话,如图所示5,显然吞吐量上不去,并且还有所下降.
为了充分发挥tomcat的潜能,需要综合评估这几个重要参数.当worker线程处理足够快的时候,可以适当提高maxConnections值,以便更多的哀求得到处理.
反之,如果后端线程处理较慢,则可考虑减少maxConnections及QueueSize,避免哀求堆积而造成哀求超时.另外NIO能更高效处理网络连接及哀求.在全栈异步的情况下,能有效减少Worker线程数.
好了到这里, java—Tomcat高性能调优方案详解就结束了,,不足之处还望大家多多原谅!!觉得收获的话可以点个关注收藏转发一波喔,谢谢大佬们支持.(吹一波,233~~)
下面和大家交流几点编程的经验:
1、多写多敲代码,好的代码与扎实的基础知识必定是实践出来的
2丶 测试、测试再测试,如果你不彻底测试本身的代码,那恐怕你开发的就不只是代码,可能还会声名狼藉.
3丶 简化算法,代码如恶魔,在你完成编码后,应回头而且优化它.从长远来看,这里或那里一些的改进,会让后来的支持人员更加轻松.
4、可以去腾讯课堂的图灵学院学习一下java架构实战案例,还挺不错的.
最后,每一位读到这里的网友,感谢你们能耐心地看完.希望在成为一名更优秀的Java法式员的道路上,我们可以一起学习、一起进步.
维易PHP培训学院每天发布《java—Tomcat高性能调优方案详解》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。
转载请注明本页网址:
http://www.vephp.com/jiaocheng/7848.html