tomcat连接池监控需通过jvm参数启用jmx,必须在setenv.sh/bat中追加catalina_opts(而非shell export),否则参数不生效;关键包括-dcom.sun.management.jmxremote、指定rmi端口与真实hostname,且datasource需使用tomcat jdbc pool工厂。

Tomcat连接池监控不依赖环境变量,硬配 JAVA_OPTS 或 CATALINA_OPTS 才是生效前提。 直接在系统级或用户级 shell 中 export 环境变量(如 export JAVA_OPTS=...)对 Tomcat 启动无效——它只影响当前 shell 进程,而 Tomcat 通常以独立进程(如 systemd、init.d 或直接调用 startup.sh)启动,不会继承这些变量。
为什么 JAVA_OPTS 和 CTALINA_OPTS 必须在启动脚本里写死
Tomcat 的 startup.sh(Linux/macOS)或 startup.bat(Windows)会显式读取 CTALINA_OPTS 和 JAVA_OPTS,并拼接到最终的 java 命令行中。JMX 监控、连接池 MBean 暴露等能力,全靠 JVM 参数触发:
-
-Dcom.sun.management.jmxremote是开启 JMX 的基础开关 -
-Dcom.sun.management.jmxremote.port=10099指定 JMX RMI 注册端口(注意:不是监听端口) -
-Dcom.sun.management.jmxremote.rmi.port=10098强制绑定 RMI 服务端口,避免随机端口导致防火墙/网络策略失败 -
-Djava.rmi.server.hostname=192.168.1.100必须设为可被监控端(如 Zabbix、JConsole)访问的真实 IP,不能用localhost或127.0.0.1 -
-Dcom.sun.management.jmxremote.authenticate=false和-Dcom.sun.management.jmxremote.ssl=false仅限内网调试;生产环境必须启用认证和 SSL
这些参数若没进 JVM 启动命令,ConnectionPoolMBean 就不会注册,任何工具都查不到 getNumActive()、getWaitCount() 等指标。
怎么安全地追加到 CTALINA_OPTS
不要覆盖原有值,用追加方式写入 $CATALINA_HOME/bin/setenv.sh(Linux/macOS)或 setenv.bat(Windows),该文件会被 Tomcat 自动 source:
export CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port=10099 \ -Dcom.sun.management.jmxremote.rmi.port=10098 \ -Djava.rmi.server.hostname=192.168.1.100 \ -Dcom.sun.management.jmxremote.authenticate=true \ -Dcom.sun.management.jmxremote.ssl=true"
关键点:
- 文件必须放在
bin/目录下,且名称严格为setenv.sh(无执行权限问题,Tomcat 会source它) - Windows 下用
setenv.bat,语法为set CATALINA_OPTS=%CATALINA_OPTS% -D... - 改完后必须重启 Tomcat,
ps aux | grep java可验证参数是否出现在进程命令行中 - 如果用 systemd 管理 Tomcat,也可能需要在 service 文件的
Environment=或ExecStart=中显式注入,此时setenv.sh会被跳过
常见错误现象与排查路径
监控工具连不上、指标为空、报 Connection refused 或 MalformedObjectNameException,大概率是以下任一环节断了:
- JVM 参数未生效 → 检查
ps aux | grep java | grep 10099是否含 JMX 参数 - RMI hostname 解析失败 → 在监控端执行
telnet 192.168.1.100 10098,不通则说明 RMI 端口未暴露或被拦截 - JMX ObjectName 不匹配 → Tomcat 连接池的 MBean 名为
Tomcat:type=DataSource,context=*,host=*,class=javax.sql.DataSource,name="jdbc/MyDB",注意引号和斜杠转义;Probe 或 Zabbix 的 item key 写错就查不到 - 连接池未启用 JMX → 确保
server.xml中<resource></resource>配置了factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"(默认值),否则用的是老版 DBCP,不支持ConnectionPoolMBean
最易被忽略的是:JMX RMI 的双端口机制(注册端口 + 服务端口)和 hostname 绑定,这两处配置错一个,整个监控链路就静默失效,且日志里往往没有明确报错。











