欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Tomcat连接性能调优

程序员文章站 2022-04-20 11:02:07
...

         Tomcat是一款非常流行的Apache的开源Web服务器。

         今天我们主要来探讨Tomcat下面的server.xml中的连接器配置对交易系统的性能影响。

         我们来假设如下一种场景:

         一种交易需要通过客户端C来远程Hessian来同步调用服务端S的服务A来完成整笔交易,客户端C设置的交易超时时间为60秒(比较简单但不精准的做法是将客户端的Hessian的连接超时时间和接收超时时间都设置成60秒);高峰期同一时刻到达客户端C的交易请求笔数为800笔;服务端对每笔交易的平均处理时间为10秒;基于客户端交易超时时间,服务端的Tomcat的Connector 中connectionTimeout也设置成60秒。

         服务端S提供的服务A是通过Hessian来暴露服务接口的,服务端程序部署在Tomcat上,Tomcat中的server.xml中连接器设置如下:

    <Connector port="8090" protocol="HTTP/1.1"   connectionTimeout="60000"   redirectPort="8443" />

只要是Web服务器,都是可以设置给客户端提供连接的最大连接数的,如果Tomcat的Connector 如上设置,则默认提供的最大连接数(即线程数maxThreads)是200,等待连接数(acceptCount)是100。即如果此时有800笔交易同时到来,由于服务端平均处理时间为10秒,所以在10秒钟之内,将有800-200-100=大约500笔交易会在客户端报超时,注意,这个超时和客户端设置的交易超时时间60秒无关,是Tomcat强制终止客户端多余的连接造成的超时。但如果你服务端处理业务的交易的平均时间不是10秒而是几毫秒甚至是不需要什么时间的,则客户端报超时的交易会远小于500笔。

          所以,根据假设的高峰期交易量800笔和服务端平均处理交易时间10秒,我们认为maxThreads设置成400、acceptCount也设置400比Tomcat的默认值更合适,这样的话,服务端可以先处理到来的800笔交易中的400笔,让另外400笔处于等待状态,等前面的400笔交易处理完成,再去等待队列中取400笔交易来处理,这样保证了处理所有的交易,也不至于让客户端等太久。

    <Connector port="8090" protocol="HTTP/1.1"  connectionTimeout="60000"  redirectPort="8443"  maxThreads="400" acceptCount="400" />

          于是有人会想,如果我高峰期并发交易有几万笔,难道我maxThreads也设置成几万?这明显是不现实也是浪费的。幸运的是Tomcat有可配置的线程连接(线程)池执行器(Executor),如下为Tomcat的默认配置:

          <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"  maxThreads="150" minSpareThreads="4"/>

           我们如何让我们的连接器使用上面的线程池执行器呢?很简单:

           <Connector executor="tomcatThreadPool"  port="8090" protocol="HTTP/1.1"  connectionTimeout="60000"   redirectPort="8443" />

            请注意,此时你的连接器Connector 就不需要设置maxThreads和acceptCount,即使你设置了,也会被Executor 的设置所覆盖。这样得话,已经没有了acceptCount的概念了。Tomcat可以在该8090端口上处理无限个客户端连接,直到客户端等待交易服务超时或Tomcat连接器设置的connectionTimeout时间超时。如果是我们现在假定的交易场景,我们的连接池执行器中的maxThreads设置成400且更合适,这样,我们能处理高峰期最大交易数为(60 / 10)  * 400 = 2400(交易超时时间和connectionTimeout中的最大值/服务端平均交易处理时间*maxThreads)笔交易,远大于原来假定的800笔交易。

            当然,所有Web容器所能同时获取的客户端连接数还和操作系统有关,这里暂不讨论。

            备注:连接器Connector是没有maxProcessors和minProcessors这两个属性的。