如何防止Tomcat服务器被CC攻击?连接器参数调优
摘要:# 给Tomcat上把锁:别让CC攻击把你的服务器“点”到冒烟 我得先说句大实话:很多中小公司的Tomcat服务器,在CC攻击面前,跟裸奔没太大区别。你可能觉得配了防火墙、上了WAF就高枕无忧了?我见过不少站点,问题恰恰不是没上防护,而是Tomcat自己…
给Tomcat上把锁:别让CC攻击把你的服务器“点”到冒烟
我得先说句大实话:很多中小公司的Tomcat服务器,在CC攻击面前,跟裸奔没太大区别。你可能觉得配了防火墙、上了WAF就高枕无忧了?我见过不少站点,问题恰恰不是没上防护,而是Tomcat自己那关没把好。配置不当,再牛的外围防护都可能被一个接一个的“点”给点穿。
这种感觉你懂吧?监控图上CPU直接拉满,响应时间飙到十几秒,用户投诉电话响个不停,但你查防火墙日志,好像又没看到什么“致命”的攻击流量。说白了,很多CC攻击打的不是漏洞,而是你服务器处理并发请求的“体力极限”。 而Tomcat,作为最终承接请求的“车间工人”,它的体力(连接器配置)直接决定了你能扛多久。
今天咱们不聊那些空泛的“部署高防”的大道理,就聚焦一件事:怎么通过调整Tomcat连接器(Connector)那几个关键参数,给你的服务器实实在在地穿上件“防弹衣”,至少别被低成本的CC攻击一碰就碎。
一、先搞明白:CC攻击是怎么“点”死Tomcat的?
想象一下,你开了一家小面馆(你的Tomcat服务器),后厨只有3个师傅(工作线程),平时同时招待10个客人(并发连接)轻轻松松。
突然,门口来了100个人(CC攻击模拟的并发请求),每个人都不点大餐,只要一碗免费凉水(发起一个消耗极小的HTTP请求),但要求必须单独用一个新碗(新建连接),而且喝完不走,就坐着慢悠悠地喝(保持连接占用)。
结果是什么?3个师傅疲于奔命地拿碗、接水、送水。真正的客人(正常用户)想点碗牛肉面?排队等着吧,等到天荒地老。更糟的是,碗柜里的碗(连接资源)很快被用光,后面的人连排队的资格都没有了——这就是 “连接数耗尽” 和 “线程池枯竭” ,服务器直接拒绝服务或者响应奇慢。
Tomcat的连接器,就是管“碗柜”(连接队列)和“师傅”(线程池)的。 调优的核心思路就两条:
- 合理限制“碗”的使用,别让恶意客人把碗全占了。
- 让“师傅”高效运转,快速处理完一个请求,赶紧服务下一个。
二、核心调优参数:给你的Tomcat拧紧“安全阀”
别怕,调优不复杂,主要就动server.xml里<Connector>标签下的几个值。咱们一个一个说人话。
1. maxConnections:控制“最大同时接待量”
- 这是啥:Tomcat能同时处理的最大连接数(包括等待的)。超过这个数,新连接直接拒绝。
- 为啥重要:这是最直接的防线。设置一个合理的上限,防止连接资源被无限占用。
- 怎么设:别傻乎乎设成几万。根据你服务器内存和实际业务量来。一个4核8G的普通应用服务器,我通常建议从
1000开始试。公式可以粗糙点:(可用内存MB / 平均每个线程占用内存MB) * 系数。但更靠谱的是看监控:在平时业务高峰时,你的最大并发连接数是多少?在这个基础上加个30%-50%的余量,就是maxConnections的参考值。 - 大实话:设太低影响正常用户,设太高等于没防。这是个平衡艺术,但有上限永远比没上限安全。
2. maxThreads:管好你的“核心工人数”
- 这是啥:Tomcat能创建来处理请求的最大工作线程数。就是上面说的“师傅”的数量。
- 为啥重要:线程是CPU调度的核心资源。线程过多,CPU会在切换线程上浪费大量时间(上下文切换开销),整体性能反而下降。
- 怎么设:这跟CPU核心数强相关。一个经典的经验公式是
maxThreads = (CPU核心数 * 2) + 10。比如4核,大概设18-25左右。但!对于Web应用,I/O等待(如查数据库)很多,可以适当调高。我一般会先用压测工具,在200-500之间找一个让系统吞吐量最高、响应时间稳定的值。 - 关键联动:
maxThreads一定要小于maxConnections。因为有些连接可能正在等待或保持连接,不一定都在干活。比例大概在maxConnections = maxThreads + 排队数。
3. acceptCount:设置“等位区”的大小
- 这是啥:当所有工作线程都忙时,新来的连接请求可以排队等待的数量。超过这个数,直接返回“连接拒绝”。
- 为啥重要:这是缓解突发流量的缓冲带。没有等位区,流量一来就拒绝,体验差;等位区太大,恶意请求排队占着茅坑,正常请求也进不来。
- 怎么设:通常设成
100-500。我个人习惯设成maxThreads的一半左右。比如maxThreads=200,acceptCount=100。记住,这个队列里的请求也是占用资源的,别设太大。
4. connectionTimeout:别让“慢吞吞的客人”赖着不走
- 这是啥:一个连接从建立后,等待请求数据的超时时间(单位毫秒)。超过时间没收到数据,就关闭连接。
- 为啥重要:CC攻击常用慢速连接(Slowloris攻击)来耗尽你的连接数。调低这个值,可以快速释放被恶意占用的连接。
- 怎么设:默认值
20000(20秒)对于防御来说太长了!对于一般HTTP服务,我强烈建议降到3000-5000(3-5秒)。一个正常的HTTP请求头,5秒内怎么也该发完了。对于API接口,甚至可以更低(2000)。调低这个值,是应对慢速攻击性价比最高的方法之一。
5. keepAliveTimeout & maxKeepAliveRequests
- 这是啥:
keepAliveTimeout是长连接保持的时间,maxKeepAliveRequests是一个连接上最多处理多少个请求。 - 为啥重要:长连接能提升正常用户体验,但恶意连接也会利用它长期占用资源。合理限制,让好连接物尽其用,让坏连接早点滚蛋。
- 怎么设:
keepAliveTimeout:从默认的20000降到5000-10000(5-10秒)。现在前端技术(HTTP/2、WebSocket)普及,传统长连接的重要性下降,可以收紧。maxKeepAliveRequests:默认100,可以适当降低到50甚至20。让连接定期重建,也能打散一些固定连接的攻击模式。
三、一个参考配置示例(供讨论)
下面是一个针对防御CC攻击调整过的NIO连接器配置示例(放在server.xml里),你可以根据自己的服务器配置(比如4核8G)调整:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxConnections="1000"
maxThreads="250"
acceptCount="100"
connectionTimeout="5000"
keepAliveTimeout="10000"
maxKeepAliveRequests="50"
redirectPort="8443"
compression="on"
compressionMinSize="1024"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/json"
/>
解释几句(私货):
- 用NIO(
Http11NioProtocol)而不是BIO,异步非阻塞,处理并发天生有优势,这是基础。 compression开启压缩,虽然增加一点CPU开销,但能大幅减少传输数据量,有时候CC攻击打的就是带宽,压缩能帮你扛更久。- 这个配置是偏防御和稳健的,不是性能极致优化的。性能极致化和安全加固,有时候目标会打架,你得自己权衡。
四、别忘了,调优不是“一锤子买卖”
- 监控先行:调之前、调之后,一定要用
jconsole、VisualVM或者APM工具看看线程数、连接数、堆内存。别瞎调。 - 压测验证:用JMeter、wrk等工具,模拟高并发请求,看看调整后的吞吐量和错误率。自己打自己,总比被攻击时才发现问题好。
- 组合拳才有效:Tomcat参数调优是最后一道防线,是“内功”。它应该和前面的“外功”(WAF的CC防护规则、高防IP的清洗、速率限制)结合使用。WAF拦掉大部分恶意IP,剩下的漏网之鱼,再用Tomcat的稳健配置扛住。
- 关注业务特性:如果你的业务就是有大量合法长连接(比如消息推送),那
keepAliveTimeout就不能设太低。一切脱离业务的配置,都是耍流氓。
写在最后
防止CC攻击,尤其是保护Tomcat这样的应用服务器,真没什么银弹。它更像是一个系统工程:从网络入口的过滤,到应用层的参数微调,再到代码层面的优化(比如避免慢SQL、用好缓存)。
今天聊的Tomcat连接器调优,就是给你服务器的“内功”扎稳马步。 它不能保证你刀枪不入,但至少能让那些想靠“人海战术”(低并发持续攻击)把你耗死的攻击,成本高上不少。
行了,别光看,拿出你的server.xml,对照着看看,是不是还开着“默认模式”在裸奔?是时候该紧一紧了。你的服务器,可能正等着你这波操作呢。

