Tomcat配置Tomcat连接池后JMX中缺失DataSource条目求助
我之前也碰到过类似的情况,给你几个一步步排查的方向,应该能解决问题:
确认数据源配置的位置与作用域
你现在把数据源配置在server.xml里,要确保它是放在<GlobalNamingResources>标签下的全局资源。如果是直接放在<Service>或<Engine>下面,Tomcat可能不会正确初始化它。正确的全局配置结构应该是这样:<GlobalNamingResources> <Resource name="MyDS" auth="Container" type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" maxTotal="50" maxIdle="10" maxWaitMillis="10000" testOnBorrow="true" validationQuery="SELECT 1 FROM DUAL" username="username" password="password" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@//database.whatever.com:1521/mydb"/> </GlobalNamingResources>另外,全局数据源需要在web应用的
WEB-INF/web.xml里添加引用才能被应用使用:<resource-ref> <description>My Global DataSource</description> <res-ref-name>MyDS</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>如果你的数据源是应用级别的(只给当前应用用),更建议放在应用的
META-INF/context.xml里,这时候它在JMX里的路径会是Catalina > localhost > 你的应用名 > DataSource > [数据源名称],而不是根路径的Dat...下面。检查数据源是否被实际初始化
Tomcat的JDBC池默认是懒加载的——只有当应用第一次调用lookup获取数据源并尝试连接时,才会真正初始化它。如果你的应用还没使用过这个数据源,JMX里自然看不到它。可以写个简单的测试代码触发初始化:Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); DataSource ds = (DataSource) envCtx.lookup("MyDS"); // 尝试获取连接触发初始化 Connection conn = ds.getConnection(); conn.close();运行这段代码后,再刷新JMX客户端看看。
确认JMX相关配置是否开启
虽然Tomcat JDBC Pool默认开启JMX监控(jmxEnabled="true"),但还是可以显式在<Resource>里加上这个参数确保生效:<Resource name="MyDS" ... jmxEnabled="true" />同时要确认Tomcat的JMX服务正常运行——检查启动脚本(比如
catalina.sh或catalina.bat)里有没有添加JMX相关的JVM参数,比如:CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"确保JMX客户端(比如jconsole、jvisualvm)连接的是正确的Tomcat进程,别连错了其他Java进程。
查看Tomcat日志排查初始化错误
如果数据源初始化失败,JMX里肯定看不到。去Tomcat的logs目录下看catalina.out或localhost.log,搜索MyDS相关的日志,有没有驱动找不到、URL错误、用户名密码不正确这类异常。比如如果oracle.jdbc.OracleDriver找不到,说明Oracle驱动包没放在Tomcat/lib目录下,把驱动包放进去重启Tomcat就行。检查Tomcat版本与数据源工厂的兼容性
你用的org.apache.tomcat.jdbc.pool.DataSourceFactory是Tomcat 7及以上版本自带的JDBC池实现,如果你的Tomcat版本是6或更早,这个工厂类不存在,应该用org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory。确认下你的Tomcat版本和配置的工厂类匹配。
按照上面的步骤一步步排查,应该能找到问题所在。
内容的提问来源于stack exchange,提问作者MichaelB

