2010-01-14 104 views
6

我有一個包含多個webapps的Tomcat實例,每個實例都可以通過/ Context訪問。 Tomcat的背後是httpd(實際上是Debian Apache2),配置了虛擬主機來爲每個應用/上下文服務。 Tomcat連接與mod_jk。從虛擬主機的URL中刪除Tomcat上下文(mod_jk,mod_rewrite)

當我不關心從網址中刪除上下文時,此功能正常工作:當請求虛擬域的根時,請求被重定向到domain.com/Context。

但是對於一個應用程序,我想要刪除上下文。我相信這可以通過使用mod_rewrite來完成,並將重寫的url傳遞給mod_jk以傳遞給正確的Tomcat上下文。所以,我的Debian Apache2的網站,提供文件看起來像這樣:

NameVirtualHost * 

<VirtualHost *> 
    ServerName domain.be 

    DocumentRoot /home/webapp/app/static/domain/ 

    RewriteEngine on 
    RewriteRule ^/(.*)$ /Context/$1 [L,PT] 
    RewriteLog "/var/log/apache2/domain-rewrite.log" 
    RewriteLogLevel 4 

    JkLogFile  /var/log/apache2/domain-mod_jk.log 
    JkLogLevel debug 
    JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " 
    JkMount /Context w1 
    JKMount /Context* w1 
    JkOptions +ForwardURICompat 

    ErrorLog /var/log/apache2/domain_error.log 
    CustomLog /var/log/apache2/domain_access.log combined 
    LogLevel warn 

</VirtualHost> 

根據該文檔時,[PT]標誌和+ ForwardURICompat選項應該導致重寫URL傳遞給jk_mod。但是,這似乎並沒有發生。

URL正在重寫,但看起來好像mod_jk忽略它:例如,將domain.be/Context的請求重寫爲/ Context/Context - 但仍然作爲/ Context傳遞給mod_jk。

任何想法?順便說一下,我目前不能使用mod_proxy。

感謝

回答

1

我一直在使用這種大獲成功:

RewriteEngine On 
RewriteCond %{REQUEST_URI} !^/(Context/.*)$ 
RewriteRule ^/(.*)$ /Context/$1 [P,L] 

說明您的情況:

  • 您將需要獲得mod_proxy的工作或[P]將被忽略並且該請求將被轉發而不是代理。這是沒有辦法的。
  • +ForwardURICompat是mod_jk的一部分,將在重寫後生效。
  • mod_jk忽略請求,因爲它永遠不會到達那裏。您需要一個RewriteCond(上面)來防止/ Context的請求被重寫。

我目前正在尋找一種方法來做到這一點沒有mod_rewrite和使用,而是,just mod_jk and Tomcat <Host>'s。但是我在apache,mod_jk和Tomcat主機很好地一起玩時遇到了麻煩。以上應該適合你。

4

@Josh,我認爲這個解決方案不會工作,如果tomcat執行任何重定向。例如,在需要登錄的應用程序中,這是典型的情況。當用戶未通過認證時,應用程序將重定向到/ login這樣的內容,但是tomcat會像在/ context/login中一樣追加當前上下文,因此最終上下文在URL中顯示。

正如你在其他問題/迴應中提到的,只使用mod-jk加上tomcat虛擬主機是一個選項,但是你需要將你的應用程序部署爲ROOT.war,這可能不那麼簡單。有一個解決方法,所以你的應用程序可以放在tomcat webapps文件夾中,但正如我所描述的here服務器將部署應用程序至少兩次。

如果RewriteRule [P]加上JkOptions + ForwardURICompat可以工作,但它不會。順便說一句,我已經測試了這一點,我知道mod_proxy的工作,因爲我代理我的網站cnn.com,我得到他們的網頁下我的網站URL。以下是日誌BTW的請求,你可以看到一個代理正在使用:

127.0.0.1 - - [15/Dec/2011:12:56:34 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/ 
127.0.0.1 - - [15/Dec/2011:12:56:34 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/ [OK] 
127.0.0.1 - - [15/Dec/2011:12:56:49 --0500] [localhost/sid#1008ef278][rid#1009aaca8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/login 
127.0.0.1 - - [15/Dec/2011:12:56:49 --0500] [localhost/sid#1008ef278][rid#1009aaca8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/login [OK] 
127.0.0.1 - - [15/Dec/2011:12:57:15 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/j_spring_security_check 
127.0.0.1 - - [15/Dec/2011:12:57:15 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/j_spring_security_check [OK] 
127.0.0.1 - - [15/Dec/2011:13:08:41 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (2) forcing proxy-throughput with http://localhost/nestorurquiza-app/ 
127.0.0.1 - - [15/Dec/2011:13:08:41 --0500] [localhost/sid#1008ef278][rid#1009980a8/initial] (1) go-ahead with proxy request proxy:http://localhost/nestorurquiza-app/ [OK] 
+1

你是對的,我的原始解決方案不是最好的方式,充滿危險。但自發布以來,我用Tomcat VirtualHosts取得了很大的成功。儘管沒有聽說過人們使用它,但在這種情況下肯定會想要使用它,而在創建之後卻一點也不難。 – 2012-06-16 17:38:42

2

我會離開我的原始答案,但它是錯誤的。這樣做的正確方法是用Tomcat的虛擬主機:

http://tomcat.apache.org/tomcat-6.0-doc/virtual-hosting-howto.html

官方步行通過上面的鏈接正是我用過好幾次了。我不會試圖在這裏把它煮沸。

該概念與Apache Vhost相同。創建一個虛擬主機(例如something.yourtdomain.com),然後將您的Web應用程序部署到該虛擬主機的ROOT應用程序(/),然後完成設置。這樣,如果您已有一個ROOT Web應用程序,則可以在另一個域中擁有另一個域,並且以前不會受到影響。

正如Nestor提到的,Apache重寫規則不會處理標記庫和框架等內容,它們會根據上下文根自動爲您創建鏈接/表單動作/ etc。在這種情況下,他們將創建正確的上下文根(/)。

+2

如果您不知道,可以將應用程序保留在webapps目錄中,並將appBase設置爲應用程序的完整路徑。 ---示例: \t \t \t skel625 2012-08-28 07:04:51

-1

使用的mod_proxy_ajp代替mod_jk的象下面這樣:

<VirtualHost *:80> 
    ServerName domain.be 

    DocumentRoot /home/webapp/app/static/domain/ 

    ... 

    ProxyPass /Context ajp://localhost:8009/Context 
    ProxyPass/ajp://localhost:8009/Context/ 

    ... 
</VirtualHost> 
+0

如果Tomcat執行任何重定向,那仍然不起作用。它根本沒有改變根本問題。沒有答案。 – EJP 2012-11-04 09:05:58

0

繼內斯特烏爾基薩的答案給出提示,我設法在tomcat的server.xml中定義額外的主機來解決問題,因爲正如所說,j_security_check請求回答通過tomcat向瀏覽器發送一個前向指令,這個指令不可避免地包含上下文名稱,以便試圖登錄的用戶獲得408個錯誤。因此,Apache VirtualHost JkMount /* worker1指令中的實際傳遞可通過制定預期的上下文來實現,即ROOT

Apache的httpd.conf [和/或所包括的*的.conf]的文件:

<!-- the subdomain --> 

<VirtualHost *:80> 
    ServerName appWelcome.example.org 
    ServerAlias www.appWelcome.example.org 
    JKMount /* worker1 
</VirtualHost> 

<!-- with mod_jk set up --> 

LoadModule jk_module modules/mod_jk.so 
JWorkersFile /etc/apache2/workers.properties 
JkShmFile  /var/log/apache2/mod_jk.shm 

所以映射作出直接子域http://appWelcome.example.org/到主管/ appWelcome Tomcat的上下文中,所有appWelcome請求上下文必須是可尋址的http://appWelcome.example.org:8080/

因此,tomcat server.xml文件將爲您正在使用的應用程序公開一個單獨的Host文件:。

<Server ...> 
    <Service> 
    <Engine defaultHost="localhost" ...> 

     <Host name="appWelcome.example.org" appBase="appWelcomeBase" ... > 
     <Valve ... /> 
     </Host> 

     <Host name="localhost" appBase="webapps" ...> 
     <!-- this Host is typically shipped with manager, host-manager, docs, 
      sample, examples and a default ROOT context that shows tomcat default home. --> 
     <Valve ... /> 
     </Host> 

    </Engine> 
    </Service> 
</Server> 

注意的權限(如果啓用SELinux的上下文中)必須調整以模仿默認Host者如下:

$CATALINA_HOME/conf/Catalina/app.example.org$CATALINA_HOME/conf/Catalina/localhost

$CATALINA_HOME/appWelcomeBase$CATALINA_HOME/webapps

何處這是做的所有剩下要做的是問題重命名和移動appWelcome.war網絡歸檔爲它自動部署在創建的appBase(用它的值替換$ CATALINA_HOME,例如/ var/www/tomcat7):

# mv $CATALINA_HOME/webapps/appWelcome.war $CATALINA_HOME/appWelcomeBase/ROOT.war 

瞧!