Quartz每次調度時被執行兩次

[關鍵字:重複執行、重複調用、每次執行兩次、執行2次]

前言:


先說一下,項目背景。由於組內某成員在用Maven搭建項目時不規範,導致項目的名稱與實際訪問項目名稱不一致。
在部署項目時,必需要配一下虛擬路徑,映射到那個項目所在目錄下去,才能正常訪問。
舉個例子:項目名稱叫student-web,部署到Tomcat-webapps下,本地環境正常情況下的訪問url應該是:

127.0.0.1:8080/student-web

而實際訪問的url需要這樣:

127.0.0.1:8080/student

0x001: 初探


那首先想到問題的解決方案就是在Tomcat的server.xml內配置虛擬路徑,來映射到實際項目。比如這樣:

1 <Host .......>
2     <Context path="/student" docBase="D:\apache-tomcat\webapps\student-web"  reloadable="true"/>
3 </Host>

吶,一開始以爲這樣問題就解決了。後來發現,實則不是。這樣做的後果是項目會被容器實例化兩次。

0x002: why?


首先需要了解<Host>標籤中的appBase屬性和<Context>標籤中的docBase屬性的作用和區別是什麼?
appBase屬性:這個目錄下面的子目錄將自動被部署爲web應用,且war文件將被自動解壓縮並部署爲web應用(默認爲Tomcat下webapps目錄)注意這句話所說的每件(個)事(點)都可以被重新配置或取消。
docBase屬性: docBase屬性位於<Context>標籤中,而<Context>標籤的作用是用於指向不在webapps下的應用的所在目錄,在tomcat啓動時docBase屬性指向的目錄下的應用也被作爲web項目同時啓動。

在有了以上了解後,那Quartz每次調度時被執行兩次方法的問題原因就找到了。

0x003: 解決方案

1.將<Host>標籤內的<Context>標籤去除,讓Tomcat自動去掃描webapps下的應用並部署。
2.若 ‘必需使用<Context>標籤’ 且 ‘必需配置虛擬路徑映射’ (注意這句話,後邊解釋),則必需將項目移出webapps目錄至某個新目錄,同時將<Context>標籤中的docBase屬性指向該新移至的目錄,如下圖


解釋一下第2條的前半句,經過測試發現,將student-web項目放到webapps目錄,且同時配置<Context>標籤的path屬性爲“/項目名稱”,啓動Tomcat,此時項目並不會跑兩遍,還是一遍,因爲path屬性指定的還是項目名稱,等於沒配置。如下:

1 <Host .......>
2     <Context path="/student-web" docBase="D:\apache-tomcat\webapps\student-web"  reloadable="true"/>
3 </Host>

 

若是配置<Context>標籤的path屬性“/非項目名稱” 且 docBase屬性指向webapps目錄,那項目肯定會被容器實例化兩遍!如下:

1 <Host .......>
2     <Context path="/student" docBase="D:\apache-tomcat\webapps\student-web"  reloadable="true"/>
3 </Host>

至於選擇哪種解決方案,根據實際情況定,那我這裏只能選擇第2種。

0x004: 聲明

導致Quartz調度任務被執行兩次的原因有很多,以上列舉的2種解決方案 可能 並 不適合你。亦可從其他方向查找原因。
比如,檢查Quartz的xml配置文件被加載了2次等等。

 

0x005: 完結
分享是技術進步的源泉,作者能力有限,如有錯誤,歡迎指出,不吝賜教。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章