一次凌晨的 PoolExhausted,让我重写了 Tomcat 连接池监控与调优方法

发布时间:2026/10/16 22:16:58

一次凌晨的 PoolExhausted,让我重写了 Tomcat 连接池监控与调优方法 一次凌晨的 PoolExhausted让我重写了 Tomcat 连接池监控与调优方法【免费下载链接】tomcatApache Tomcat项目地址: https://gitcode.com/gh_mirrors/tom/tomcat凌晨 2:47值班群被报警刷屏下单接口 P99 从 300ms 爬到 3.2s日志里开始出现org.apache.tomcat.jdbc.pool.PoolExhaustedException。重启没用扩容也没用——直到我们把 Tomcat 连接池监控接进告警才发现活跃连接数死死卡在 20 纹丝不动后面排队的线程越攒越多。说白了池子早就打满了只是我们一直看不见。这篇文章讲的不是连接池 API 大全而是三个具体问题怎么把池子的状态实时摊开来看tomcat-jdbc JMX监控、连接池耗尽时如何一步步定位根因连接池耗尽诊断、参数到底该怎么调Tomcat连接池调优。一、连接池的黑箱里到底发生了什么先建立一个直觉。把数据库连接想成银行柜台的窗口一个连接 一个窗口maxActive 窗口总数getNumActive() 正在办业务的窗口数getNumIdle() 空着的窗口数getWaitCount() 已经取了号、坐在椅子上等叫号的人数泄露的连接 拿了号却赖在座位上不走的人这套指标全部定义在 ConnectionPoolMBean 接口中。但问题在于你在context.xml里写下的 maxActive、minIdle 只是开业方案开业之后窗口每天被借走几次、有没有人占座不走、每次办业务花多久——这些池子自己不会主动上报。没有观测手段时你只能靠用户投诉来猜池子的状态。这次事故的教训就是参数配得好 ≠ 池子运行得好连接池监控必须成为常态化能力而不是出事后的临时补丁。真正值得盯的指标只有五个各自异常时你看到什么活跃连接数长期贴住 maxActive 不动说明池子饱和容量和占用时长至少有一个出了问题空闲连接数持续为 0 表示一点缓冲都没有任何毛刺都会变成排队等待数 waitCount本次事故的主角持续为正就是池子被打满的直接证据借出/归还计数差值借出数减归还数理论上应长期稳定在活跃连接数附近像图书馆用外借总量倒查失窃的书泄露回收计数被强制回收的连接数涨一个就说明线上有一个真实的泄露点二、 把连接池的状态摊开来看JMX 相当于给 Java 进程装了一块仪表盘进程把内部状态注册成 MBean外部工具通过端口读数值、调方法。连接池的仪表盘节点就是org.apache.tomcat.jdbc.pool:name池名。开启 Tomcat JMX 远程访问的完整步骤修改启动脚本追加 JVM 参数然后jconsole连上host:1099在 MBeans 标签下逐层展开找到池子节点CATALINA_OPTS$CATALINA_OPTS \ -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port1099 \ -Dcom.sun.management.jmxremote.rmi.port1099 \ -Dcom.sun.management.jmxremote.authenticatetrue \ -Dcom.sun.management.jmxremote.password.file\$CATALINA_BASE/conf/jmxremote.password代码方式拉取指标适合写自定义巡检脚本或内部监控面板MBeanServer mbs ManagementFactory.getPlatformMBeanServer(); ObjectName on new ObjectName( org.apache.tomcat.jdbc.pool:typeDataSource,context/orders,namejdbc/MyDB); int active (int) mbs.getAttribute(on, NumActive); int waiters (int) mbs.getAttribute(on, WaitCount);生产环境的完整链路一般长这样指标最终落到 Grafana 上按 15s 粒度出曲线三、 连接池耗尽时的三步诊断流程拿到曲线之后别急着调参。我们沉淀下来的诊断顺序是三步每一步都有明确的判断标准。第一步看 waitCount确认够不够用。active 贴住 maxActive 且 waitCount 持续为正说明池子已打满waitCount 间歇性尖峰但几秒内回落说明只是峰值流量打穿容量。判断标准waitCount 连续 5 分钟大于 0基本可以锁定容量不足或有人不还连接二选一。第二步借出/归还对比区分不够用还是不还。拉出 borrowedCount 与 returnedCount 的增长曲线。两者同步上涨且 active 长期高位说明连接正常还回、只是每笔业务占用时间变长——这时池子参数没问题锅在 SQL 或事务粒度上。反过来借出涨得快、归还跟不上差值持续走高的那段就是没还回来的连接数指向泄露。本次事故里两条曲线斜率一致排除了泄露把嫌疑转给了单条连接占用时间。第三步removeAbandonedCount 慢查询日志锁定最后一环。前者在涨直接确认泄露给池配上logAbandonedtrue再调 MBean 的checkAbandoned()强制触发一轮检测日志会打印每个被回收连接借出时的完整堆栈行号直接指向问题代码——比任何猜测都快。后者用于排除泄露之后在池的jdbcInterceptors里挂SlowQueryReportJmx超过阈值的 SQL 会发 JMX 通知MBean 上还能按语句查出最慢耗时Resource namejdbc/MyDB authContainer typejakarta.sql.DataSource urljdbc:mysql://db.internal:3306/orders driverClassNamecom.mysql.cj.jdbc.Driver maxActive20 minIdle2 removeAbandonedtrue removeAbandonedTimeout120 logAbandonedtrue jdbcInterceptorsorg.apache.tomcat.j2ee.pool.interceptor.SlowQueryReportJmx(threshold800)/回到凌晨那次事故第 1 步定位到池子打满第 2 步排除泄露第 3 步慢查询报告里全是SELECT ... WHERE order_no ?单条查询每条 40~60ms、单请求循环执行 30 次——当天灰度上线的订单导出接口写了个 N1还漏关了一个 Statement。修复后曲线立刻回落。四、 参数怎么调跟着现象走现象先看再调active 长期贴住 maxActivewaitCount 间歇为正业务是否真变慢maxActive上调如 20→30waitCount 为正借出/归还基本同步SQL 耗时先治慢查询别动容量removeAbandonedCount 在涨借出堆栈removeAbandonedTimeout调小如 120→60createdCount / releasedCount 高频抖动连接寿命minIdle上调、timeBetweenEvictionRunsMillis拉长调优顺序比参数本身更重要三步诊断没过之前不要碰容量参数。泄露场景下扩池只是把爆掉的时间从一小时推迟到三小时慢查询场景下扩池只是把瓶颈从连接池推到数据库连接数和锁竞争上tomcat 连接池性能分析的终点永远应该落在 SQL 和事务边界。本次的完整动作与效果N1 循环查询改成一次 IN 查询maxActive20→30minIdle2→10SlowQueryReportJmx阈值 800ms上线前调 MBean 的resetStats()清零统计、压测建立基线。对比数据waitCount 从持续 5~15 回落到 0active 稳定在 8~12 而不是贴死 30接口 P99 从 3.2s 降到 210ms数据库侧的连接数也终于不再一路涨。五、可以贴进运维手册的检查清单确认 JMX 远程访问已开启且配了authenticate与密码文件密码文件权限 400端口只对监控网段开放确认池 MBean 已注册jconsole 能看到org.apache.tomcat.jdbc.pool节点指标可拉取配置告警waitCount 连续 5 分钟 0 定级 P1removeAbandonedCount 环比增长 0 同样 P1生产环境保持removeAbandonedtrue与logAbandonedtrue堆栈信息是泄露定位的捷径SlowQueryReportJmx阈值按业务 P95 响应时间的 1/3 设定而不是照抄默认值每次发布后跑一遍压测先resetStats()再采集建立本次版本的指标基线把active 贴满 waitCount 爬升写进事故响应手册要求 10 分钟内给出容量/SQL/泄露三选一的初步结论监控的价值不在曲线本身而在下次 waitCount 开始爬升时你已经有办法在 10 分钟内说清楚问题是容量、SQL 还是代码。【免费下载链接】tomcatApache Tomcat项目地址: https://gitcode.com/gh_mirrors/tom/tomcat创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/9 9:43:00

基于Grok构建AI应用:从工具调用到生产部署的完整实践

在实际 AI 应用开发领域,将大型语言模型(LLM)的能力封装成可交互、可复用的应用,正从少数开发者的探索变为一种标准化的工程实践。Grok 作为近期备受关注的 AI 模型,其应用构建功能的全面开放,意味着开发者…

2026/10/16 14:32:50

DSH插件市场:借鉴《我的世界》组合包理念,打造高效开发工具链

在开发工具链生态中,插件市场是提升开发效率和扩展功能边界的关键组件。近期,一个名为 DSH 的插件市场因其独特的“组合包”理念而受到关注,它借鉴了《我的世界》模组组合包的思路,为开发者提供了一种全新的插件管理与集成体验。本…

2026/10/9 2:29:53

乏了<从2026回到2015的那天>

时常会想这是不是我就要的生活,生活所陪伴的不是动听的音乐,不是繁华激荡的人生,而是一种和电脑交道的程序员,不是讨伐这个职业,只是觉得上班、下班的生活什么时候才会变成是另外一种生活的开首。心头萦绕一种乏……大…

2026/10/16 22:14:09

33岁转行AI大模型来得及吗?关键路径与实战指南

最近总有读者在后台问我类似的问题:“我今年33岁,不是科班出身,现在开始转行AI大模型,还来得及吗?看到网上都在喊这是泼天的富贵,我是不是已经错过了?”隔着屏幕都能感觉到那种焦虑——一边是铺…

2026/10/16 22:14:09

RAG检索失败怎么办?用知识图谱增强检索的14个实战案例

做RAG(检索增强生成)项目做得久了,你会发现一个规律:用户抱怨最多的,往往不是生成效果,而是检索结果。文档库里明明躺着正确答案,模型就是找不到;问A答B的有,张冠李戴的有…

2026/10/16 22:14:09

大模型优化器选型指南:AdamW与LAMB的工程本质与实操阈值

1. 为什么大模型训练不用SGD,而要反复折腾优化器名字?“AdamW”和“LAMB”这两个词,最近几年在大模型训练日志里出现的频率,几乎和CUDA out of memory一样高。但有意思的是,很多刚从CV/NLP基础课程转来做大模型微调的同…

2026/10/16 22:14:09

sapjco3.jar for Mac 64 配置指南:dylib、java.library.path 与常见坑

简介:面向Mac 64位平台的sapjco3.jar是SAP官方发布的Java连接器组件,主要面向Java后端开发者和企业系统集成工程师,用于解决在macOS 64位环境下通过RFC接口远程调用SAP系统中的函数模块,打通Java应用与SAP R/3或NetWeaver之间的数…

2026/10/16 22:09:08

堆排序算法实验报告:Java实现与JUnit断言验证

简介:本资源是一份面向算法初学者与计算机专业学生的堆排序算法综合实验报告,以Java语言实现,帮助读者系统掌握堆排序的建堆、调整与排序全过程。压缩包内共1个doc文档,约63KB,内容涵盖算法流程图、关键代码、复杂度分…

2026/10/16 5:33:43

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/16 4:03:48

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/15 13:42:16

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/16 0:01:11

Cephadm实战指南:Linux系统工程师的生产级Ceph集群部署与排障

简介:本资源是一份完整的Ceph分布式存储系统中文技术文档合集,面向Linux系统运维工程师、云平台架构师及存储方向开发者,帮助读者系统掌握Ceph集群的部署、配置与运维核心能力。文档覆盖对象存储(RGW)、块设备&#xf…

2026/10/16 0:01:11

ITK中SpatialObject几何体系解析:坐标系、变换与管道集成

1. 空间对象的定位:为什么 ITK 需要一套几何描述体系很多刚开始接触 ITK 的朋友,包括我自己,最初都是被它的图像滤波、配准、分割这些“正统”功能吸引进来的。等真正上手做点实际项目,比如把分割出来的器官边界做量化分析、给血管…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑