2009-02-24 36 views
15

我目前正在研究j2ee項目,這個項目現在已經在測試階段了。現在我們只是解決部署過程中的一些問題。具體來說,戰爭中嵌入了許多文件(某些xml文件和.properties),需要根據您是否處於開發,測試或生產環境中進行不同的版本部署。像記錄等級,連接池等東西如何管理java webapps中的嵌入式配置文件和庫?

所以我想這裏的開發人員如何構建他們的流程部署web應用。您是否儘可能多地嚮應用程序服務器卸載配置?您是否在部署之前以編程方式替換設置文件?在構建過程中選擇一個版本?手動編輯戰爭?

還能走多遠,你在通過應用服務器的靜態庫提供的依賴性去多少你把在戰爭中的自己?所有這些只是爲了瞭解一下當前常見的(或者最好的)做法。

回答

6

我在一個單獨的服務器團隊爲我們的應用程序執行QA和生產服務器配置的環境中工作。每個應用程序通常部署在兩臺QA服務器和三臺生產服務器上。我的開發團隊已經發現,通過在戰爭(或耳朵)中儘可能多地配置儘可能多的配置,最大限度地減少服務器上所需的配置數量。這使得服務器配置更容易,同時也最大限度地減少了服務器團隊錯誤配置服務器的可能性。

我們沒有機器特定的配置,但是我們確實有特定於環境的配置(開發,質量保證和生產)。我們有存儲在war文件中的配置文件,這些文件由環境命名(例如,dev.properties,qa.properties,prod.properties)。我們在服務器虛擬機的java命令行上放置一個-D屬性來指定環境(例如java -Dapp.env = prod ...)。應用程序可以查找app.env系統屬性並使用它來確定要使用的屬性文件的名稱。

我想,如果你有一個少數特定的機器性能,那麼你可以指定它們作爲-D性能以及。 Commons Configuration提供了一種將屬性文件與系統屬性相結合的簡單方法。

我們在服務器上配置連接池。我們命名連接池在任何環境相同,只是指向分配給每個環境相應的數據庫服務器。應用程序只需知道一個連接池名稱。

+0

大部分答案都是說同樣的,接受這個,因爲我們可能最終會做非常相似的東西。 – wds 2009-03-02 08:32:13

8

我認爲,如果屬性是特定機器/部署,那麼他們所屬的機器上。如果我打算在戰爭中包裝,它應該是無用的,這意味着它沒有特定於它所運行的機器。如果戰爭具有與機器相關的屬性,這個想法就會失效。

我喜歡做的是建立一個properties.example文件的項目,每臺機器都有一個的.properties是住的地方戰爭可以訪問它。

的另一種方法是將有螞蟻的任務,例如開發戰爭,階段戰爭,產品戰爭,並且擁有這些項目的一部分,並在戰爭中建成。我不太喜歡這一點,因爲你最終會將單個服務器上的文件位置等作爲項目構建的一部分。

0

我把所有的配置放在數據庫中。容器(Tomcat,WebSphere等)讓我可以訪問初始數據庫連接,從此以後,所有內容都從數據庫中傳出。這允許多個環境,集羣和動態更改,而無需停機(或至少不需要重新部署)。特別好的是能夠即時更改日誌級別(儘管您需要管理員屏幕或後臺刷新器來獲取更改)。顯然這隻適用於啓動應用程序時不需要的事情,但通常情況下,您可以在啓動後很快到達數據庫。

2

我通常做的兩個屬性文件:

  • 一個內嵌在應用程序的詳細資料(郵件,內部的「魔」字),
  • 其他的環境細節(DB訪問,日誌級別&路徑......)暴露在每個服務器的類路徑上並「粘貼」(不隨我的應用程序交付)。通常我會根據目標env「mavenise」或「anttise」來放置特定的值。
  • 酷哥使用JMX來維持他們的應用程序配置(CONF可以實時修改,而無需重新部署),但它是我的需求太複雜。

服務器的(靜態?)庫:我強烈反對服務器庫使用我的應用程序,因爲它增加依賴於服務器:

  1. IMO,我的應用程序必須是「自我包裝」:我扔下戰爭,就是這樣。我已經看到戰爭中有20 Mbs的罐子,這對我來說並不令人不安。
  2. 一個常見的最佳做法是將您的外部依賴性限制在J2EE教條所提供的內容上:J2EE API(使用Servlet,Ejbs,Jndi,JMX,JMS ...)。你的應用必須是「服務器不可知論者」。
  3. 在您的應用程序中添加依賴項(war,ear,wathever)是自我記錄:您知道應用程序依賴於哪些庫。有了服務器庫,你必須清楚地記錄這些依賴關係,因爲它們不太明顯(很快你的開發人員就會忘記這個小魔術)。
  4. 如果您升級您的應用服務器,您所依賴的服務器庫的機會也將發生變化。 AppServer編輯器不應該從版本到版本維護其內部庫的兼容性(大多數情況下,它們不會)。
  5. 如果您使用嵌入在您的appServer中的廣泛使用的庫(jakarta commons logging,又名jcl,想起)並且想要升級它的版本以獲得最新功能,那麼您承擔appServer將不會支持的巨大風險它。
  6. 如果您依賴靜態服務器對象(在服務器類的靜態字段中,例如Map或日誌),則必須重新啓動應用服務器才能清理此對象。您失去熱重新部署應用程序的能力(舊的服務器對象在重新部署之間仍然存在)。使用appServer範圍內的對象(不同於J2EE定義的對象)會導致微妙的錯誤,特別是如果這個對象在多個應用程序之間共享。這就是爲什麼我強烈建議不要使用駐留在appServer庫的靜態字段中的對象。

如果你絕對需要「這個對象在此應用程序服務器的罐子」,嘗試將罐子複製你的應用程序,希望有其他服務器的罐子沒有依賴性,並檢查您的應用程序的類加載策略(我坐習慣把在我所有的應用程序上都有一個「最後一個父類」類加載策略:我相信我不會被服務器的罐子「污染」 - 但我不知道它是否是「最佳實踐」)。

4

wrt配置文件,我認爲Steve's答案是迄今爲止最好的答案。我想補充使得相對於戰爭文件的安裝路徑的外部文件的建議 - 這樣你可以有不同的配置的一臺服務器戰爭的多次安裝。

例如如果我的dev.war被解壓到/opt/tomcat/webapps/dev中,那麼我將使用ServletContext.getRealPath來查找基礎文件夾和war文件夾名稱,因此配置文件將相對於戰爭生存在../../config/dev或絕對地生存在/opt/tomcat/config/dev

我同意Bill關於儘可能少地放在這些外部配置文件。根據您的環境使用數據庫或JMX來存儲儘可能多的數據。 Apache Commons Configuration有一個nice object用於處理由數據庫表支持的配置。

關於圖書館,我同意unknown在戰爭文件(自封裝)WEB-INF/lib文件夾中的所有庫。優點是應用程序的每次安裝都是獨立的,並且您可以同時使用不同版本的庫來構建不同的戰爭版本。

缺點是它會使用更多的內存,因爲每個Web應用程序都有它自己的類的副本,由它自己的類加載器加載。

如果這引起了真正的擔憂,那麼您可以將jar放入servlet容器的公用庫文件夾(對於tomcat爲$CATALINA_HOME/lib)。但是,運行在同一服務器上的所有Web應用程序的安裝必須使用相同版本的庫。 (其實,這是不完全正確,你可以在必要時把壓倒一切的版本在個人WEB-INF/lib文件夾,但是這變得相當混亂維護。)

我會打造爲公共庫的自動安裝程序在這種情況下,使用InstallShield或NSIS或等同於您的操作系統。有些東西可以很容易地告訴你是否擁有最新的一系列庫,以及升級,降級等。

相關問題