杜绝假死,Tomcat容器做到自我保护,设置最大连接数

该文章来自阿里巴巴技术协会(ATA)精选集

前提说明

为了确保服务不会被过多的http长连接压垮,我们需要对tomcat设定个最大连接数,超过这个连接数的请求会拒绝,让其负载到其它机器。达到保护自己的同时起到连接数负载均衡的作用。

动手去做

一开始根据故障todoList提供的参数MaxKeepAliveRequests,进行验证,我们将tomcat配置server.xml修改为:

同时,启动客户端模拟30个长连接。

预期应该只有10个连接能保持住。
结果与预期不符,30个连接都连上了,而且正常。
这由此怀疑提供的配置参数是否是真正限制最大连接数的含义了。

KeepAlive是在HTTP1.1中定义的,用来保持客户机和服务器的长连接,通过减少建立TCP Session的次数来提高性能。常用的配置参数有{KeepAlive, KeepAliveTimeout, MaxKeepAliveRequests}。逐个说来:
KeepAlive是决定开启KeepAlive支持;
KeepAliveTimeout决定一 个KeepAlive的连接能保持多少时间,Timeout就尽快shutdown链接,若还有数据必须再建立新的连接 了;
MaxKeepAliveRequests于KeepAliveTimeout相似,意思是服务多少个请求就shutdown连接。

显然与我们想到的要求不符,再搜索其它配置参数:

maxConnections
根据字面意思觉得就应该是这个了。
去验证吧,
!
最大连接数为10,我们启动30个长连接,
预期应该是只有10个长连接,实际结果却是远超过10个。这个有点不应该啊。

实验验证

原来还有个参数可以觉得连接数的大小

maxThreads:tomcat起动的最大线程数,即同时处理的任务个数,默认值为200
acceptCount:当tomcat起动的线程数达到最大时,接受排队的请求个数,默认值为100

这两个值如何起作用,请看下面三种情况
情况1:接受一个请求,此时tomcat起动的线程数没有到达maxThreads,tomcat会起动一个线程来处理此请求。
情况2:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,tomcat会把此请求放入等待队列,等待空闲线程。
情况3:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,等待队列中的请求个数也达到了acceptCount,此时tomcat会直接拒绝此次请求,返回connection refused

同时加上maxConnections

原来tomcat最大连接数取决于maxConnections这个值加上acceptCount这个值,在连接数达到了maxConenctions之后,tomcat仍会保持住连接,但是不处理,等待其它请求处理完毕之后才会处理这个请求。

源码分析

tomcat的最大连接数参数是maxConnections,这个值表示最多可以有多少个socket连接到tomcat上。BIO模式下默认最大连接数是它的最大线程数(缺省是200),NIO模式下默认是10000,APR模式则是8192(windows上则是低于或等于maxConnections的1024的倍数)。如果设置为-1则表示不限制。

在tomcat里通过一个计数器来控制最大连接,比如在Endpoint的Acceptor里大致逻辑如下:

while (running) {
    ...
    //if we have reached max connections, wait
    countUpOrAwaitConnection(); //计数+1,达到最大值则等待

    ...
    // Accept the next incoming connection from the server socket
    socket = serverSock.accept();

    ...
    processSocket(socket);

    ...
    countDownConnection(); //计数-1
    closeSocket(socket);
}

计数器是通过LimitLatch锁来实现的,它内部主要通过一个java.util.concurrent.locks.AbstractQueuedSynchronizer的实现来控制。

我们将最大连接数设置为10,同时启动超过30个长连接,
然后通过jstack可以看到acceptor线程阻塞在countUpOrAwaitConnection方法上:

http-nio-8080-Acceptor-0" daemon prio=10 tid=0x00007f9cfc191000 nid=0x1e07 waiting on condition [0x00007f9ca9fde000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076595b688> (a org.apache.tomcat.util.threads.LimitLatch$Sync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:969)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1281)
        at org.apache.tomcat.util.threads.LimitLatch.countUpOrAwait(LimitLatch.java:115)
        at org.apache.tomcat.util.net.AbstractEndpoint.countUpOrAwaitConnection(AbstractEndpoint.java:755)
        at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:787)
        at java.lang.Thread.run(Thread.java:662)

代码层面也解释了这种现象。

总结

tomcat能支持最大连接数由maxConnections加上acceptCount来决定。同时maxThreads如何设定?

以下部分结论引用自:http://duanfei.iteye.com/blog/1894387
一般的服务器操作都包括两方面:1计算(主要消耗cpu),2等待(io、数据库等)

第一种极端情况,如果我们的操作是纯粹的计算,那么系统响应时间的主要限制就是cpu的运算能力,此时maxThreads应该尽量设的小,降低同一时间内争抢cpu的线程个数,可以提高计算效率,提高系统的整体处理能力。

第二种极端情况,如果我们的操作纯粹是IO或者数据库,那么响应时间的主要限制就变为等待外部资源,此时maxThreads应该尽量设的大,这样 才能提高同时处理请求的个数,从而提高系统整体的处理能力。此情况下因为tomcat同时处理的请求量会比较大,所以需要关注一下tomcat的虚拟机内 存设置和linux的open file限制。

现实应用中,我们的操作都会包含以上两种类型(计算、等待),所以maxThreads的配置并没有一个最优值,一定要根据具体情况来配置。

最好的做法是:在不断测试的基础上,不断调整、优化,才能得到最合理的配置。

acceptCount的配置,我一般是设置的跟maxThreads一样大,这个值应该是主要根据应用的访问峰值与平均值来权衡配置的。

如果设的较小,可以保证接受的请求较快相应,但是超出的请求可能就直接被拒绝

如果设的较大,可能就会出现大量的请求超时的情况,因为我们系统的处理能力是一定的。

时间: 2024-09-17 03:39:05

杜绝假死,Tomcat容器做到自我保护,设置最大连接数的相关文章

2003应用池假死常见问题和解决方法

经常见到大家谈起,2003应用池自动死了,不能恢复了 一直出现  Service Unavailable 常见方法如下. 1:以前没有SP1打补丁的时候会出现这个IIS6.0假死问题,但现在微软都在自动更新里面出补丁了,一般你打好最新补丁后是不会出现此问题了.(所以现在的IIS假死与这个关系不是很大) 2:从IIS6.0开始CPU资源都在应用池里面限制了,不象以前的IIS.5.所以假死的池的缘故就是池被拉死,你在网站打不开的时候可以看到你的某个应用池是禁用的,上面出现一个红叉.你鼠标右键启动网站

Sring mvc +mybatis部署tomcat导致tomcat启动假死

问题描述 Sring mvc +mybatis部署tomcat导致tomcat启动假死 mybatis如果出现如下错误会导致tomcat假死并且等待很长时间才报错,错误信息不准确,导致tomcat栈溢出,修改了tomcat内存参数之后,错误原因可以看出来,但是tomcat终端一直报错,停不下来,求解Spring公共配置 <!-- 使用annotation 自动注册bean, 并保证@Required.@Autowired的属性被注入 --> <context:component-scan

tomcat每天启动后,晚上无人操作,但第二天铁定假死,线程dump已抓,请各位帮忙分析一下问题所在

问题描述 2014-07-0110:42:45FullthreaddumpJavaHotSpot(TM)64-BitServerVM(20.0-b11mixedmode):"RMITCPConnection(3)-10.238.206.233"daemonprio=6tid=0x00000000082df800nid=0x436crunnable[0x000000001951f000]java.lang.Thread.State:RUNNABLEatjava.net.SocketInp

控件-急急急!!!!vb程序数据量比较大时VSflexgrid设置数据源假死机怎样解决????

问题描述 急急急!!!!vb程序数据量比较大时VSflexgrid设置数据源假死机怎样解决???? 使用vsflexgrid控件查看数据,当数据量比较大时(超过十万行),设置vsflexgrid数据源时程序假死机,等待一段时间才有响应,求大神指点!!! 解决方案 .Redraw一共有三个取值: flexRDNone --不刷新数据,要手工刷新数据才会显示 flexRDDirect --立即装入所有的数据,你应该是设置成了这个,所以速度慢 flexRDBuffered --显示部分数据,这种速度最

Windows画图程序假死的原因

尽管当前能后期编辑图片的软件很多,但笔者粘贴屏幕抓图.将BMP文件另存为JPG格式时,还是喜欢 使用Windows自带的画图程序.不过,在使用画图程序却遇到了奇怪的问题:当想保存图片时,只要指定 保存位置和文件名后点击"保存"按钮就会出现画图程序无响应,只能强制结束进程,因此造 成画图程序无法正常工作! 这是怎么回事呢?笔者还真头一次遇到,于是"搜畅刮肚"的来寻找画图程序"假死 "的真正原因-- 尝试一:莫非"画布"太大? 具

Windows XP任务栏假死现象解密

使用了一段时间的Windows XP后,相信很多朋友都曾遇到过这样的问题:电脑在用着用着时,突然任务栏不起作用了,点击后没有任何效果,犹如死机一般,但桌面还正常,片刻过后,故障会自行恢复正常.这就是Windows XP任务栏假死现象.微软也推出了专门的补丁程序来解决这个问题,你可以下载Windows XP任务栏假死补丁. 但好像打上补丁后,问题依然没有彻底解决,这其中和Windows XP提供的输入法状态条可以进行位置随意移动有很大关系,我做了一下实验发现,关闭输入法状态条后任务栏出现假死的现象

讯飞输入法手机版假死问题怎么解决

  讯飞输入法手机版假死问题怎么解决 讯飞输入法,如果开启了中文词联想功能,输入中文文字后, 点击中英文切换按钮,从中文切换到英文,就会频频出现假死现象. 初步分析,在关闭中文联想之后,可以减少90%的假死现象. 测试版本:iFly V5.0.1760 测试机型:Coolpad 8017 测试系统:Android 4.4.2 讯飞输入法 解决方法: 假如在输入状态下,点击讯飞输入法选项图标, 然后点击右下角的设置按钮. 讯飞输入法 点击左边的"输入法设置"; 点击第一个按钮"

只需一分钟轻松搞定Win7桌面假死问题

很多使用Win7的用户都会遇到一个问题就是关于Win7桌面假死的情况,如何来避免这种不必要的麻烦呢,重装系统吗?这当然是个不太明智的选择,如果不重装系统,但是电脑会时不时的卡上一段时间,这也会让广大用户恼火一阵了.那么是因为什么原因Win7会出现假死的情况呢?首先要确定你购买 Win7安装的是正版系统,这不仅确保Win7桌面不会经常出现蓝屏的状况,也维护了你购买Win7的权益.其次,我来介绍给大家几种遇到Win7假死的情况下如何解决的方法. Win7桌面 一.开机的时候电脑出现假死 在开机进入桌

Windows 7假死的情景与处理方法

Windows 7虽好,可是小问题不断.从Beta版本至今,很多朋友遇到最严重的问题就是资源管理器偶尔或者经常失去响应,虽然不是什么非重装的问题,但是时不时电脑卡上一段时间,谁都觉得很烦.那么到底Windows 7在哪些情况下会出现这样的问题,又应该如何来解决,这是今天来探讨的问题. 情景一:开机假死 开机就假死一般情况是在进入桌面之后,鼠标就变成圆圈状,一直在忙碌状态,会持续很长一段时间,要结束的话只有强制关机. 出现这一类问题的原因比较多,可以从几个方面来看.首先,最好不要安装各种所谓的Wi