Tomcat报registered the JDBC driver [Oracle.jdbc.driver.OracleDriver] but failed to unregister it
来源:互联网 发布:zynq linux 编辑:程序博客网 时间:2024/05/16 07:31
很久没写博客了,项目中用的是pooxl.0.9.1连接池,连接池自带相应的bug已修复
tomcat运行或者reaload之后,tomcat运行出现 如下异常:
严重: The web application [/XXX] registered the JDBC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
The web application [/XXX] appears to have started a thread named [HouseKeeper] but has failed to stop it. This is very likely to create a memory leak.
刚开始怀疑是tomcat连接池,资源在关闭的时候没有释放,导致内存泄露,tomcat6.0.2X之后,推出一个防止内存泄漏的监听,目录为/conf/server.xml 中
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />把他注释掉,也没好用,还是同样出这种问题,由于是在生产环境也不能随意更换tomcat版本,所以继续想别的办法,后来想到既然jdbc没有释放,何不在关闭tomcat 服务的时候,手动来关闭呢,于是想到了增加一个ServletContextListener监听:首先在web.xml中加入一个监听:
<listener> <listener-class> com.xx.dbprovider.DBPooxDriverListener </listener-class></listener>
然后让DBPooxDriverListener实现ServletContextListener接口,在contextDestroyed对所有的驱动进行关闭
public class DBPooxDriverListener implements ServletContextListener {private ServletContextEvent context=null;@Overridepublic void contextDestroyed(ServletContextEvent destoryContext) {// TODO Auto-generated method stub Enumeration<Driver> drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { Driver driver = drivers.nextElement(); try { DriverManager.deregisterDriver(driver); } catch (SQLException e) { e.printStackTrace(); } } System.out.println("关闭所有数据库连接"); //destroyThreads(); }@Overridepublic void contextInitialized(ServletContextEvent context) {// TODO Auto-generated method stubcontext=this.context;}/** * 销毁未正常关闭的线程 */private void destroyThreads(){ final Set<Thread> threads = Thread.getAllStackTraces().keySet(); for (Thread thread : threads) { if(thread.getName().equals("HouseKeeper")){ synchronized (this) { try { thread.stop(); return; } catch (Exception e) { e.printStackTrace(); } } } }} }
然后发布,重启,关闭,在重启,这样保证手动把未正常关闭jdbc连接,关闭掉,可是运行了几天,又出现了如下错误:
The web application [/XXX] appears to have started a thread named [HouseKeeper] but has failed to stop it. This is very likely to create a memory leak.
这次不报jdbc相关连接未关闭,后来又加上了,如上注释掉的 //destroyThreads();方法,在关闭tomcat的时候,同时关闭掉这个线程,就好了,用jdk自带的工具jvisualvm.exe,在jdk安装目录找到即可,不过需要在tomcat的bin/catalina.bat 配置一下:
set JAVA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9080 -Dcom.sun.management.jmxremote.authenticate=false - Dcom.sun.management.jmxremote.ssl=false
然后tomcat在运行状态,直接双击jvisualvm.exe文件,既可以打开,可以对tomat做相应的监控。
如果如上办法还是不能解决的话,可以尝试做一个守护程序,当tomcat挂掉,或者宕机重启tomcat,不过此方法,不是最好的办法,在这简单说下这个方法,做一个简单页面,然后用URLConnection 定时去连接tomcat服务器,如果返回有内容,说明tomcat正常,如果返回失败,说明tomcat存在异常,需要用到java.lang.Runtime.getRuntime().exec(tomcatRoot+"bin//shutdown.bat"),有的用net start tomcat6 命令,需要把服务注册到系统服务里,操作起来感觉挺麻烦的,直接这样就可以,也不同注册服务,然后开启一个线程,设定一个定时去连接tomcat,一旦发生异常,重启就可以,下面是代码,不过此代码有这样的一个弊端,必须要把tomcat启动后的等待时间设置稍微长一些,否则会导致tomcat连续开启多个tomcat,下面是代码,大家可以交流探讨下:
/** * tomcat 服务监听守护线程 * @author lt * */public class TomcatMonitor implements Runnable { String start=""; //系统命令 启动 String stop=""; //系统命令 关闭 String testHttp=""; //测试连接地址 String tomcatRoot=""; //tomcat根目录 int testIntervalTime=1;//测试连接间隔时间,单位为秒 int waitIntervalTime=2; //等待测试间隔时间,单位为秒 int testTotalCount=5; //测试连接总次数 Thread thread=null; public TomcatMonitor(){ ResourceBundle config= ResourceBundle.getBundle("config"); try { stop=config.getString("stop"); start=config.getString("start"); testHttp=config.getString("testHttp"); tomcatRoot=config.getString("tomcatRoot"); testIntervalTime=Integer.parseInt(config.getString("testIntervalTime")); waitIntervalTime=Integer.parseInt(config.getString("waitIntervalTime")); testTotalCount=Integer.parseInt(config.getString("testTotalCount")); } catch (Exception e) { e.printStackTrace(); } System.out.println("*******************初始化成功!*******************"); thread=new Thread(this); thread.start(); } public void run() { System.out.println("正在监控中..."); int testCount=0; while (true) {testCount=0; testCount++; boolean isrun=checkStatus(); System.out.println("正在启动测试连接,尝试连接次数为:"+testCount+",结果为:"+(isrun==false?"失败.":"成功! ")+ getCurrentTime()); //检测状态 while (!isrun) { if(testCount>=testTotalCount)break; try {thread.sleep(testIntervalTime*1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} testCount++; System.out.println("正在启动测试连接,尝试连接次数为:"+testCount+",结果为:"+(isrun==false?"失败.":"成功! ")+getCurrentTime()); isrun=checkStatus();} //先关闭,后启动服务 while (!isrun) {try {System.out.println("正在执行关闭......");Runtime.getRuntime().exec(tomcatRoot+"bin//shutdown.bat");//先执行关闭thread.sleep(8000);System.out.println("正在重新启动......");Runtime.getRuntime().exec(tomcatRoot+"bin//startup.bat");//启动thread.sleep(waitIntervalTime*1000); System.out.println("重启tomcat成功");isrun=checkStatus();//重启后,再次连接看是否正常 } catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("重启tomcat异常,请查看先关错误信息"); }} try { thread.sleep(waitIntervalTime*1000); } catch (InterruptedException e) { e.printStackTrace(); } }}/** * 检查服务器状态 * @return true:运行正常 ;false:服务器发生异常 */public boolean checkStatus() {URL url=null;InputStreamReader in=null;try {url=new URL(testHttp);URLConnection urlConn=url.openConnection();urlConn.setConnectTimeout(15000);urlConn.setReadTimeout(4000);in=new InputStreamReader( urlConn.getInputStream());BufferedReader reader = new BufferedReader(in);//实例化输入流,并获取网页代码 String s; while ((s = reader.readLine()) != null) { System.out.println("返回值:"+s); return true; } } catch (IOException e) {// TODO Auto-generated catch block//e.printStackTrace();System.out.println(e.getMessage());return false;}finally {if (in!=null) {try {in.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("关闭文件流失败****");}}}return false;}public String getCurrentTime() {SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return sdf.format(new Date());} public static void main(String[] args) throws Exception{ TomcatMonitor tm=new TomcatMonitor();// tm.run();// String tomcatRoot="D:/apache-tomcat-6.0.35restart/";// Process p= java.lang.Runtime.getRuntime().exec(tomcatRoot+"bin//startup.bat");//启动// java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream())); /* String tomcatRoot="D:/apache-tomcat-6.0.35restart/"; Process p= java.lang.Runtime.getRuntime().exec(tomcatRoot+"bin//shutdown.bat");//启动 java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream())); String s; boolean restart = false; String t = "Server startup in"; while ((s = in.readLine()) != null) { System.out.println(s); if (s.indexOf(t) != -1) { restart = true; break; } }*/ } }
下面是配置文件:
#测试连接总次数 testTotalCount=3 #连接失败时,再次检测时间间隔,单位为秒 testIntervalTime=3 #连接超时时间,即多少秒tomcat没响应视为宕机,单位为秒 connectionTimeout=15 #tomcat启动时间,防止在tomcat尚未启动完成的时候,程序又去检验tomcat状态,造成尚未启动完成又重新启动,单位为秒 tomcatStartTime=600 #测试连接地址 testHttp=http://127.0.0.1:9080/SpringMvcMQ/login#testHttp=http://192.168.31.156:8080/nhip/enterapp.do?method=begin&name=/ESBManager&welcome=/ESBManager/pages/index.jsp#tomcat根目录tomcatRoot=D:/apache-tomcat-6.0.35restart/ #正常情况下,每次检测间隔时间,单位为秒 waitIntervalTime=90放到web.xml做监听:
<listener> <listener-class>com.neusoft.nhip.monitor.TomcatMonitorListener</listener-class> </listener> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list>tomcat服务一启动就会执行该守护线程,同时更加明了的看到tomcat的运行状态
- Tomcat报registered the JDBC driver [Oracle.jdbc.driver.OracleDriver] but failed to unregister it
- registered the JDBC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister it when the
- registered the JDBC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister it when the
- A web application registered the JBDC driver [oracle.jdbc.OracleDriver] but failed to unregister it
- tomcat 启动报错 registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister
- registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it
- 使用DBCP出现registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it
- tomcat 问题 registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister
- application registered the JDBC driver [com.mysql] but failed to unregister it when the web app...
- registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web applica问
- SpingMVC registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the we
- 循环依赖 导致 registered the JDBC driver [oracle.jdbc.OracleDriver] but failed to unregist
- The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister i
- The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister
- The web application [/jcs] registered the JDBC driver[oracle.jdbc.driver. OracleDriver] but failed
- registered the JDBC driver [com.microsoft.jdbc.sqlserver.SQLServerDriver] but failed to unregister
- registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister
- web项目异常A web application registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister
- web及spring配置web简介(一)
- c#接口
- 循环队列
- MySQL命令
- 过年回家
- Tomcat报registered the JDBC driver [Oracle.jdbc.driver.OracleDriver] but failed to unregister it
- XML DOM nodeType 属性值代表的意思
- IDEA环境下搭建JMeter3.1二开环境步骤
- delphi如何保存和读取utf-8的文本文件
- log4j 学习笔记
- 郑州:2016年城市竞争的最大赢家
- day04--this应用
- 微信小程序
- Android开源商城