tomcat调优中配置Executor和Connector

<Connector port="80" protocol="HTTP/1.1" maxThreads="600" minSpareThreads="100" maxSpareThreads="500" acceptCount="700" connectionTimeout="20000" /> 

maxThreads="X" 表示最多同时处理X个连接

minSpareThreads="X" 初始化X个连接

maxSpareThreads="X" 表示如果最多可以有X个线程,一旦超过X个,则会关闭不在需要的线程

acceptCount="X" 当同时连接的人数达到maxThreads时,还可以排队,队列大小为X.超过X就不处理

 <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"

         maxThreads = "500"  minSpareThreads = "20"  maxSpareThreads = "50"  maxIdleTime = "60000" />

maxThreads :Tomcat 使用线程来处理接收的每个请求,这个值表示 Tomcat 可创建的最大的线程数,默认值是 200

minSpareThreads:最小空闲线程数,Tomcat 启动时的初始化的线程数,表示即使没有人使用也开这么多空线程等待,默认值是 10。

maxSpareThreads:最大备用线程数,一旦创建的线程超过这个值,Tomcat 就会关闭不再需要的 socket 线程。




网上很多混淆了,异步servlet和非阻塞connector,一个是Executor,一个是connector,两者的工作阶段不同。

 

connector:

这个是指,外部IP连接到服务器,好比抢票软件在抢12306的火车票,因此一坨一坨的连接到12306。因此,会有很多connection(连接),建立、维护、管理这些连接,这就是connector要做的事情。显然这是web服务器性能的重要指标。即,可支持的每秒最大连接数。

connector,可以采用,blocking I/O,nio,ajp,apr

Servlet:

一个Servelet,就是一个线程一次的执行过程。比如响应doGet(),这个是在一个独立的线程中完成的。

当connector建立连接后,服务器会分配一个线程(可能是从线程池)去服务这个连接,即执行doGet等方法,执行完,回收线程。显然这一步是一个同步的过程,tomcat对应的是Executor

 

  • 显然,具体实现由多种方式:connector和Servlet可以共用一个线程,这种web服务方案,即为 每连接一个线程 Connection per thread。每次来个请求,服务器便创建一个线程(或者线程池中选择线程)由于线程不可能无限制增加,当线程比较多时,服务负载会很大。

这种方式的优点是,简单,适合CPU型

 

  •  Request per thread 每请求一个线程,即等到具体服务请求时,才独立分配线程方式。而这个线程通常是在线程池中分配,如果没有空闲的执行线程,那么请求会被挂起,当请求挂起的数目(即排队数)超过预设最大请求数(tomcat中maxConnections值),服务会拒绝服务器(Service Unavailable)。apache,tomcat等主流实现方案都采用这种方式。 

说明:网上很多人都以为,第二种方式,实现了高并发、高吞吐。其实,是因为第二种模型是适合常见的web服务特点,即大量的短连接(IO密集型,服务处理时间很短,大约50ms以内,但连接数很多),处理完即关闭连接,当服务是批处理类的大作业服务(CPU密集型,服务处理时间很长,常需要1秒以上,但连接数少),第二种方式不如第一种,每连接就分配一个线程运行。

 

此时,Connector和Servlet(Executor)也可以不共用一个线程,一个维护连接,Executor用独立的线程来服务,

tomcat采用的就是这种方式。而维护连接connector部分,常见的可以采用阻塞和非阻塞方式。实际上,tomcat8提供4种protocol:

org.apache.coyote.http11.Http11Protocol - blocking Java connector
org.apache.coyote.http11.Http11NioProtocol - non blocking Java connector
org.apache.coyote.http11.Http11Nio2Protocol - non blocking Java connector
org.apache.coyote.http11.Http11AprProtocol - the APR/native connector.

tomcat8.0.15原文文档如下:

Each incoming request requires a thread for the duration of that request. If more simultaneous requests are received than can be handled by the currently available request processing threads, additional threads will be created up to the configured maximum (the value of the maxThreads attribute). If still more simultaneous requests are received, they are stacked up inside the server socket created by the Connector, up to the configured maximum (the value of the acceptCount attribute). Any further simultaneous requests will receive "connection refused" errors, until resources are available to process them.

 

可以看出,tomcat使用了线程池,线程最多增加到maxThreads ,如果还有请求进来,那么这些请求就会wait在connector上,如果connector上wait的请求超出了acceptCount ,那么服务器就返回 "connection refused"拒绝连接错误。

 

所以,此时,Servlet的线程数,最大maxThreads ,但连接数则最大为acceptCount

_________________________________________________________________________________

 

 

CONNECTOR之间的比较 

 Java Blocking Connector
BIOJava Nio Blocking Connector
NIOJava Nio2 Blocking Connector
NIO2APR/native Connector
APRClassnameTomcat VersionSupport PollingPolling SizeRead HTTP RequestRead HTTP BodyWrite HTTP ResponseWait for next RequestSSL SupportSSL HandshakeMax Connections
Http11ProtocolHttp11NioProtocolHttp11Nio2ProtocolHttp11AprProtocol
3.x onwards6.x onwards8.x onwards5.5.x onwards
NOYESYESYES
N/AmaxConnectionsmaxConnectionsmaxConnections
BlockingNon BlockingNon BlockingBlocking
BlockingSim BlockingBlockingBlocking
BlockingSim BlockingBlockingBlocking
BlockingNon BlockingNon BlockingNon Blocking
Java SSLJava SSLJava SSLOpenSSL
BlockingNon blockingNon blockingBlocking
maxConnectionsmaxConnectionsmaxConnectionsmaxConnections

 

 

Connecotr和Executor的关系,其实可以类比nginx的主进程和工作进程


<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"connectionTimeout="20000" redirectPort="8443"/>
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000" redirectPort="8443"/>
<Connector executor="tomcatThreadPool" port="8080"protocol="HTTP/1.1" connectionTimeout="20000"redirectPort="8443" />
<Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"connectionTimeout="20000" redirectPort="8443" />
我们姑且把上面四种Connector按照顺序命名为 NIO, HTTP, POOL, NIOP
为了不让其他因素影响测试结果,我们只对一个很简单的jsp页面进行测试,这个页面仅仅是输出一个Hello World.假设地址是http://tomcat1/test.jsp
我们依次对四种Connector进行测试,测试的客户端在另外一台机器上用ab命令来完成,测试命令为:
ab -c 900 -n 2000 http://tomcat1/test.jsp
最终的测试结果如下表所示(单位:平均每秒处理的请求数):
NIO HTTP POOL NIOP
281 65   208  365
666 66   110  398
692 65   66   263
256 63   94   459
440 67   145  363
由这五组数据不难看出,HTTP的性能是很稳定,但是也是最差的,而这种方式就是Tomcat的默认配置.NIO方式波动很大,但没有低于280的,NIOP是在NIO的基础上加入线程池,可能是程序处理更复杂了,因此性能不见得比NIO强;而POOL方式则波动很大,测试期间和HTTP方式一样,不时有停滞.由于linux的内核默认限制了最大打开文件数目是1024,因此此次并发数控制在900.尽管这一个结果在实际的网站中因为各方面因素导致,可能差别没这么大,例如受限于数据库的性能等等的问题.但对我们在部署网站应用时还是具有参考价值的.
我们来看一下配置,你只需要在server.xml里把HTTP Connector做如下更改,
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000" 
redirectPort="8443" />
改为
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000" 
redirectPort="8443" />
然后启动服务器,你会看到org.apache.coyote.http11.Http11NioProtocolstart的信息,表示NIO已经启动.其他的配置请参考官方配置文档.

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值