2010-01-14 53 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 

瞧!