1. 程式人生 > >阿里雲伺服器部署war包報錯:The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but ...

阿里雲伺服器部署war包報錯:The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but ...

熬了整整3天,靠著不解決不罷休的精神,終於把這個問題解決了。期間看了很多資料,網上的資料大部分抄來抄去,有用的太少,真正用到的就那麼幾篇文章,本想把這幾篇文章連結貼上來,但一看瀏覽的歷史記錄太多了,懶得一個個去找了。歸根到底還是自己太水,基本功不紮實。希望能幫到你。

問題背景:一個專案(WEB-INF目錄下有lib資料夾,存放一部分第三方jar包【後面出的問題之一與這個有關】)在我本機(window7+JDK1.8+Tomcat8)上執行正常,部署到一臺阿里雲伺服器(centos7.4+JDK1.8+Tomcat8)上後,訪問專案地址報404錯誤,檢視日誌顯示如下警告(重要的三個地方已標紅):

WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [] registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [] registered the JDBC driver [com.mysql.jdbc.Driver

] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [] appears to have started a thread named [Abandoned connection cleanup thread
] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:

意思網上解釋的很清楚:就是上一次程式結束的時候,沒有登出資料庫驅動,重新啟動後,為防止記憶體洩露,不允許重複註冊驅動。

回想第一次上傳war包時,忘記關閉Tomcat了,應該就是這樣的熱部署導致Tomcat關閉時,未能正確登出資料庫驅動。為驗證這個想法,我把war包上傳到了另一臺阿里雲伺服器(centos7.4+JDK1.8+Tomcat8),這次記得上傳之前把Tomcat關了,上傳完畢再啟動,果然可以正常訪問了。心想這種問題很簡單啊,直接重啟系統就行,然而重啟之後問題依舊;懶得仔細查原因了,直接簡單粗暴重灌系統,這下總算可以了吧。費了好大的勁重灌系統,配置環境,裝資料庫,當我信心滿滿等待著瀏覽器裡出現專案首頁的美麗臉龐時,又一個 404 砸來,充滿期待的表情立馬變得一臉懵逼。這都不行??這是要鬧哪樣???看來不是系統的問題,但是為啥另一臺伺服器就可以正常訪問呢?系統都是一樣的呀。阿里這麼牛逼的公司,伺服器有問題的可能性不大,還是靜靜的尋找一下專案的問題吧。

第一:實現監聽器並註冊

把前兩段警告放到網上搜,大多數都是說把  lib 下的資料庫驅動 jar 包放到 Tomcat 目錄下就好了,照做後無效。痛苦的煎熬中~~~。我以為後面的報錯都是前面的報錯引起,就只想著搜前兩條警告了。絕望之中試著搜一下第三條警告,看到了一絲希望,需要自己寫一個登出資料庫驅動的監聽器:

監聽器類:

public class WebAppContextListener implements ServletContextListener {
	
	@Override
	public void contextDestroyed(ServletContextEvent event) {
		System.out.println("webService stop");
		
        try {
            while(DriverManager.getDrivers().hasMoreElements()) {
                DriverManager.deregisterDriver(DriverManager.getDrivers().nextElement());
            }
            System.out.println("jdbc Driver close");
            AbandonedConnectionCleanupThread.shutdown();
            System.out.println("clean thread success");
        } catch (SQLException e) {
            e.printStackTrace();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
	}
	@Override
	public void contextInitialized(ServletContextEvent event) {
		
		Const.WEB_APP_CONTEXT = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
		
	}

}

將這個類註冊到 web.xml :

<listener>
		<listener-class>你的監聽類所在的包名.WebAppContextListener</listener-class>
</listener>

第二;升級 Druid  驅動版本

好了,這下應該沒問題了吧。但還是報404 ,稍微感到一點安慰的是,錯誤日誌的第三條警告變了:
 The web application [] appears to have started a thread named [Druid-ConnectionPool-Create-155769601] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:

繼續搜,說是 Druid 驅動版本的問題,我看了一下專案中的 Druid 版本是 1.0.9,換成 1.0.20 後,這條警告消失了,但是前兩警告依然堅挺的直立在那裡,任由狂風暴雨,紋絲不動。我又陷入了絕望~~~。

第三:清理 lib 目錄

之前搜問題時,有答案說要把 lib 目錄下的資料庫驅動 jar 放到 Tomcat 下,雖然嘗試之後無效,但給了一個找問題的思路。推測應該是 lib 下的 jar 包 和 Tomcat 的 jar 包衝突,索性把  lib 目錄下的  jar 包全刪了(當然刪之前要做備份,留下幾個maven倉庫裡沒有的第三方 jar 包),這次提示缺少資料庫驅動,加入 jar 包:mysql-connector-java-5.1.34.jar  。功夫不負有心人,冰凍的心靈終於迎來了春天,終於看到了嬌羞動人的首頁。【最終 Tomcat 下 lib 資料夾內的 jar 保持安裝 Tomcat 後的初始狀態不變 】

第四:設定資料庫表名大小寫敏感屬性

煎熬到此應該結束了吧,正準備被自己的努力感動得流淚時,點選首頁的登入按鈕,卻一點反應都沒有,趕緊把噴出的淚水塞回眼睛,繼續看日誌:

Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'SYS_USER' doesn't exist

什麼?明明一大張表擺在那裡,竟然說找不到?? 原來 MySQL表名 預設 大小寫敏感,要來點印度神油讓它不敏感。

參考這位童鞋:https://blog.csdn.net/she_lock/article/details/82143031

  • 修改/etc/my.cnf
  • [mysqld]節點下,加入一行: lower_case_table_names=1
  • 重啟 MySQL 即可。 (service mysqld restart)

 

==========================================分割線===============================================

終於可以長驅直入專案頁面了,這是一種前所未有的快感!《完》