背景:
企業環境下使用域名輪詢 + 多臺tomcat 來平衡負載,tomcat之間共享數據庫,因爲沒用到session所以並沒有做tomcat集羣的配置。多個tomcat之間會使用rsync文件同步來同步工程文件,舉例說來就是,用一臺服務器作爲主服務器,一旦主服務器上的jsp文件更新那麼會定時同步到其他服務器上去。
問題描述:
主服務器上jsp頁面更新,主服務器訪問頁面更新生效,從服務器訪問頁面沒有更新。
問題猜想1:
更新沒有生效首先就懷疑頁面文件同步出了問題。
問題排查1:
主從服務器上取下頁面文件進行對比,發現頁面文件無差異,但是通過tomcat顯示出來的頁面就是沒更新。
問題猜想2:
tomcat在更新jsp之後沒有及時編譯jsp文件爲class,導致頁面訪問效果沒有更新。
問題排查2:
進入到tomcat的work目錄下面,將主從服務器的頁面編譯後的java和class文件做了比較,發現不一致,問題果然出在這裏。
那麼爲什麼jsp頁面更新了之後tomcat沒有檢測到更新並且自動更新編譯成java或者class呢?
結論:
首先,我們確定配置了<Context reloadable="true">,tomcat會去檢測jsp的更新重新編譯。
然後,再深入一點了解tomcat的檢測機制,我們發現,tomcat是這麼做的:
tomcat是根據文件的更新日期判斷jsp文件是不是比現有的編譯好的.java文件新來決定是否重新編譯。(這個來源於資料,沒有驗證:http://daidalei321.iteye.com/blog/909999)
那麼極有可能問題就出在這裏,查看了下發現主從服務器的時間果然沒有同步,從服務器比主服務器快了幾分鐘。假設從服務器比主服務器快了10分鐘,這樣的話就可能發生如下的過程:
主服務器 : 時間00:00(新增Jsp文件) -> 時間00:01(更新jsp文件,文件更新時間戳爲00:01)
從服務器 : 時間00:10(同步得JSP,編譯class時間戳爲00:10) -> 時間00:11(得到更新的jsp文件更新時間戳爲00:01比本地編譯的class00:10晚,判斷爲不更新)
於是乎杯具產生了。
所以這種情況下的解決辦法就是同步主從服務器系統時間。