2014-06-11 20 views
3

我有很多不同的獨立(無狀態)Web服務以Java編寫並編譯爲WAR文件。我想將它們部署到單個Web應用程序服務器。我可以擁有多個具有重疊路徑的Java webapps嗎?

如果每個WAR文件中的服務處理的URI都以前綴作爲Web應用名稱開頭,那麼這很容易。我可以,例如,有

銷售WAR文件:包含以下代碼:
GET http://example.com/sales/widgets
POST http://example.com/sales/widgets
GET http://example.com/sales/sky-hooks

MARKETING WAR文件:包含代碼如下:
GET http://example.com/marketing/widgets
PUT http://example.com/marketing/sky-hooks

...在這種情況下,我想簡單地部署以商品名「銷售」和「市場營銷」兩個WAR文件。但是,我不是那麼幸運。相反,組件處理的URI路徑重疊。事情是這樣的:

銷售WAR文件:包含以下代碼:
GET http://example.com/widgets/sales
POST http://example.com/widgets/sales
GET http://example.com/sky-hooks/sales

MARKETING WAR文件:包含以下代碼:
GET http://example.com/widgets/marketing
PUT http://example.com/sky-hooks/marketing

我的問題是我怎麼(如果有的話)可以在單個Web應用程序服務器上部署這些。

我很樂意接受需要大量工作的建議。例如,我最好的想法是在常規URI路徑之前構建期望使用組件名稱前綴的服務,然後通過知道每個URI模式落入哪個組件的不同服務器管理所有傳入流量,並將URI修改爲添加該前綴。這種方法的難點在於像Swagger這樣的工具可以讀取我的源代碼,它們對URI的外觀會有一個錯誤的想法。

任何想法?

+1

我假設將它們組合成一個大的戰爭文件是不是因爲某些原因? – DrLivingston

+0

你沒有獎勵賞金的任何特定原因? – nont

+0

nont(和其他人):我真的對此感到抱歉...我意外地被叫走了,然後在一個星期內沒有上網就度假。賞金已經被授予,理所應當。 – mcherm

回答

0

明顯的slotuion是重命名戰爭或重構,以便適當的映射在正確的位置。

還有什麼將是一個有點哈克,你不能改變戰爭的名字,甚至soemthing象下面這樣:

SALES WAR FILE: contains code for the following: 
GET http://example.com/webapp1/widgets/sales 
POST http://example.com/webapp1/widgets/sales 
GET http://example.com/webapp1/sky-hooks/sales 

MARKETING WAR FILE: contains code for the following: 
GET http://example.com/webapp2/widgets/marketing 
PUT http://example.com/webapp2/sky-hooks/marketing 

你也可以創建一個路由/過濾另一場戰爭,即適當地重定向所有內容 - 但這也依賴於改變網址。

+0

事實上,如果我可以在每個URL上加上一個WAR名稱的前綴,那麼根本衝突並不重要。我希望有人能夠提出的建議是:「哦,這個晦澀的選項註冊了多個元素,並省略了戰爭名稱。」或者通過某種方式來轉換URI,然後將它們轉換回來(所以Swagger會起作用)。 – mcherm

6

如果你願意把在Apache的Web容器的面前,你可以使用apache's mod_proxy to forward request to the right place.

其中一種方法可以工作,將被部署在不同前綴的獨立戰爭中的第一種情況(銷售,營銷),然後使用的ProxyPass的請求發送到正確的地方:

ProxyPass /widget/sales http://example.com/sales/widget 
ProxyPass /sky-hooks/sales http://example.com/sales/sky-hooks 

ProxyPass /widget/marketing http://example.com/marketing/widget 
ProxyPass /sky-hooks/marketing http://example.com/marketing/sky-hooks 

它可能是一個更好的主意,只是重構你的路由,雖然 - 這可能是很難維持的。

(編輯:我原來提出的mod_rewrite,但我想讓我的回答更具體的,它看起來像這可能純粹以代理來完成)

+0

我認爲這是一個很好的建議,雖然OP說這些東西有一個「大集合」,所以這個解決方案會得到一個。單調乏味,而且b。需要與代碼不斷重新同步。也許可以做些什麼來自動生成Apache配置。 – DrLivingston

1

首先,決定如何部署可以被配置

您確定絕對URI必須重疊嗎?上下文根將作爲每個服務支持的路徑的前綴,除非絕對路徑已被編碼到應用程序本身中。第一步是通過獨特的上下文根或應用程序實例直接訪問每個WAR文件。

選項1:設置上下文根爲每個WAR文件中明確

的戰爭文件的上下文根被設置在部署時。對於某些服務器,可以使用外部部署描述符將其設置在Web應用程序之外。對於Tomcat,它可能嵌入在META-INF/context.xml中。有關更多信息,請參閱http://tomcat.apache.org/tomcat-7.0-doc/config/context.html

選項2:使用多個容器

分離上下文根實例或者,部署每個WAR文件到Java EE servlet容器的一個單獨的實例,在不同端口上分別運行。這將解決硬編碼絕對路徑中的部署衝突。

最後,通過Apache設置虛擬主機和代理的請求和MOD_JK

一旦上下文根實例已作出唯一易於通過上述方法之一,配置Apache的一個實例來充當一個反向代理。首先,建立一個虛擬主機來處理外部可見URI的請求。接下來,配置mod_jk將請求路由到正確的WAR文件部署。有關更多詳細信息,請參閱http://tomcat.apache.org/connectors-doc/webserver_howto/apache.html

後記

上述解決方案的方法是通用的用於這種類型的問題,將需要Apache和Tomcat配置,其被選擇作爲示例反向代理和Java EE servlet的技術及其執行的一些知識。有關部署約束的更多細節將有助於確定最佳解決方案。總的來說,確定可能發生變化的硬約束與可能未發生變化的約束應引導您快速找到解決方案。

4

如果我正確理解你的問題,解決辦法之一是(我假設Tomcat的使用,但這個應該適用於最現代的servlet容器):

1)部署你的銷售和市場營銷戰爭與不同的前綴。即使用你的榜樣,他們應該能夠服務於下列網址:

GET http://example.com/sales/widgets/sales 
POST http://example.com/sales/widgets/sales 
GET http://example.com/sales/sky-hooks/sales 

GET http://example.com/marketing/widgets/marketing 
PUT http://example.com/marketing/sky-hooks/marketing 

2)使用UrlRewriteFilter手藝將被部署到你的servlet容器根前綴(Tomcat的它被稱爲ROOT.war)輕量級的Web應用程序並會重寫傳入請求中的URL以指向相關的Web應用程序。

換言之,輸入的請求等:

/widgets/sales 

將被變換到:

/sales/widgets/sales 

...和遞送到web應用sales

同樣,在響應的網址,如:

/sales/widgets/sales 

將被改寫爲:

/widgets/sales 

3)部署這場戰爭給你的servlet容器的根。

這種方法有點類似於@nont提出的方法,但不需要apache作爲前端,因爲重寫功能將由根web應用程序處理(UrlRewriteFilter基本上實現了mod_rewrite功能)。

換句話說,您將能夠將所有應用程序(包括部署到根前綴的此重寫應用程序)部署到單個服務器,從而減輕對額外中間代理/重寫服務器的需求。

0

這是一個反向代理的用例。如果您的Web服務器是Apache,則可以使用@nont proxy_mod建議創建反向代理。

我知道IBM Http Server(IHS)也允許這個mod。

相關問題