一个tomcat
一个tomcat,不是那只橘色胖猫,是Apache Tomcat——Java世界里最老实的那个servlet容器。我用了它十年,从Tomcat 6到Tomcat 9,它始终像个不爱说话的后端同事,不抢功,不添乱,但偶尔闹脾气时能让你凌晨三点蹲在机房抓头皮。 Tomcat的脾气其实很好懂。你往webapps里丢一个war包,它默默解压,默默启动线程池,默默监听8080端口。它不会像某些新框架那样给你整出花里胡哨的控制台动画,启动日志就那几行,最后一行“Server startup in [xxx] milliseconds”出现,你就知道它能干活了。这个“xxx”数字很诚实,机器快就是快,慢就是慢,不像某些云服务商宣传的“秒级启动”,实际要等半分钟。 但Tomcat的“老实”里藏着倔强。有次我部署一个内存泄漏的应用,连续三天,每天下午四点准时OutOfMemoryError。查了堆转储,发现是某个第三方库缓存了HttpSession,而Tomcat默认的session管理器不会主动回收。我调了maxIdleBackup、minIdleSwap这些参数,像给老牛调缰绳——它不反抗,但效果有限。最后我干脆写了个定时任务,每天凌晨三点重启Tomcat,治标不治本,但业务没再投诉。后来换了Tomcat的PersistentManager,把session序列化到磁盘,才根治。这老家伙的配置项多得像本字典,你翻得越仔细,它越服帖。 Tomcat最让我服气的一点,是它对“线程”的抠门。默认配置下,一个请求占一个线程,线程池满了就排队,队列满了就拒绝连接。这种朴素模型在微服务时代显得笨拙,但恰恰是这种笨拙,让它的行为可预测——你压测时看线程数曲线,就知道瓶颈在哪,不像某些异步框架,事件循环一乱,排查问题像在大雾里找路灯。有一次我同时跑三个Tomcat实例,每个只分配256MB堆内存,照样扛住了一天两百万次请求。你说它性能好吗?不算顶尖,但稳定得像钟表。 当然,稳定不代表不会翻车。去年我遇到一个诡异问题:Tomcat每隔七天就卡死一次,线程dump显示所有线程都停在“SocketInputStream.read”上,像是被什么东西卡住了。我翻遍catalina.out,没见异常。后来偶然发现是服务器的iptables规则里有一条对8080端口的“每秒10个连接”限制,而Tomcat的连接器在等待keep-alive连接时,被防火墙悄悄掐了。那感觉就像你家的老水管,不是水压不够,是阀门被隔壁邻居拧了小半圈。Tomcat自己不会报错,它只是默默等,等到超时,然后清掉连接,继续干活。 现在新项目都爱用Spring Boot内嵌Tomcat,一个jar包跑起来,连webapps目录都省了。这确实方便,但少了点仪式感——以前你部署一个war包,要看Tomcat解压时的进度条,要检查logs目录下的localhost.log,要手动改server.xml里的端口。那种“亲手喂大一只猫”的掌控感,现在没了。不过话说回来,Tomcat就像工具箱里的老扳手,你未必天天用,但真需要拧紧某个生锈的螺丝时,它比任何电动工具都让你放心。 这年头什么都讲云原生、容器化,Tomcat还在那老老实实解析着HTTP/1.1,处理着servlet的init和destroy。它不追新,但也不落伍——Java 21都出了,它照样跑得好好的。有时候我会想,技术圈最稀缺的,可能不是那些天天换新框架的“弄潮儿”,而是像Tomcat这种,十年如一日把基础活干到极致的“老黄牛”。它不会出现在技术分享会的PPT里,但你的每一个请求,它都认真对待。
- 最近发表
- 随机阅读
- 搜索
-
- 友情链接
-