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: 完結
分享是技術進步的源泉,作者能力有限,如有錯誤,歡迎指出,不吝賜教。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM