2010-01-14 9 views
6

Tôi có một cá thể Tomcat duy nhất chứa một số ứng dụng web, mỗi ứng dụng có thể truy cập thông qua nó/Ngữ cảnh. Tomcat đứng sau httpd (thực sự là Debian Apache2), được cấu hình với các máy chủ ảo để phục vụ từng ứng dụng/Ngữ cảnh. Kết nối Tomcat với mod_jk.Xóa ngữ cảnh Tomcat khỏi URL cho máy chủ ảo (mod_jk, mod_rewrite)

Điều này hoạt động tốt khi tôi không quan tâm đến việc xóa ngữ cảnh khỏi url: khi thư mục gốc của miền ảo được yêu cầu, yêu cầu được chuyển hướng đến domain.com/Context.

Tuy nhiên đối với một ứng dụng, tôi làm muốn xóa ngữ cảnh. Tôi tin rằng điều này có thể được thực hiện bằng cách sử dụng mod_rewrite và chuyển url được viết lại thành mod_jk để chuyển sang ngữ cảnh Tomcat chính xác. Vì vậy, tôi tập sites-available Debian Apache2 trông như thế này:

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> 

Theo các tài liệu, các [PT] cờ và + ForwardURICompat tùy chọn nên kết quả trong URL viết lại được thông qua để jk_mod. Tuy nhiên điều đó dường như không xảy ra.

URL đang được viết lại, nhưng dường như mod_jk bỏ qua nó: Yêu cầu cho miền.be/Context chẳng hạn được viết lại thành/Context/Context - nhưng vẫn được chuyển đến mod_jk dưới dạng/Ngữ cảnh.

Bất kỳ ý tưởng nào? Ngẫu nhiên, tôi không thể sử dụng mod_proxy tại thời điểm này.

Cảm ơn

Trả lời

1

Tôi đã sử dụng điều này với thành công rực rỡ:

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

Ghi chú về tình hình của bạn:

  • Bạn sẽ cần phải có được làm việc mod_proxy hoặc [P] sẽ bị bỏ qua và yêu cầu sẽ được chuyển tiếp thay vì được ủy quyền. Không có cách nào xung quanh chuyện này.
  • +ForwardURICompat là một phần của mod_jk và sẽ có hiệu lực sau khi viết lại.
  • mod_jk bỏ qua yêu cầu bởi vì nó không bao giờ đến đó. Bạn cần một số RewriteCond (ở trên) để ngăn các yêu cầu đến/Bối cảnh không bị viết lại.

Tôi hiện đang tìm cách để thực hiện việc này mà không cần mod_rewrite và sử dụng, thay vào đó, just mod_jk and Tomcat <Host>'s. Nhưng tôi đang gặp rắc rối với apache, mod_jk và Tomcat host chơi độc đáo với nhau. Ở trên sẽ làm việc tốt cho bạn.

4

@Josh, tôi nghĩ giải pháp này sẽ không hoạt động nếu tomcat thực hiện bất kỳ chuyển hướng nào. Đây là trường hợp điển hình, ví dụ trong một ứng dụng yêu cầu đăng nhập. Khi người dùng không được xác thực, ứng dụng sẽ chuyển hướng đến một cái gì đó như/login tuy nhiên tomcat sẽ chắp thêm ngữ cảnh hiện tại như trong/context/login để ở cuối ngữ cảnh hiển thị trong URL.

Như bạn đã đề cập trong câu hỏi/phản hồi khác của bạn bằng cách sử dụng mod-jk cộng với máy chủ ảo tomcat là một tùy chọn nhưng ở đó bạn sẽ cần phải triển khai ứng dụng của bạn dưới dạng ROOT.war có thể không đơn giản. Có một giải pháp thay thế để ứng dụng của bạn có thể được thả vào thư mục webapps tomcat nhưng như tôi đã mô tả here máy chủ sẽ triển khai ứng dụng ít nhất hai lần.

Thật tuyệt vời nếu RewriteRule [P] cộng với JkOptions + ForwardURICompat có thể hoạt động nhưng không.BTW Tôi đã thử nghiệm điều này và tôi biết mod_proxy làm việc như tôi proxied trang web của tôi để cnn.com và tôi đã nhận trang của họ theo URL trang web của tôi. Dưới đây là nhật ký BTW cho các yêu cầu mà bạn có thể thấy một proxy đang được sử dụng:

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

Bạn đúng là giải pháp ban đầu của tôi không phải là cách tốt nhất và đầy nguy hiểm. Nhưng kể từ khi đăng bài đó, tôi đã sử dụng Tomcat VirtualHosts với nhiều thành công. Mặc dù không nghe nói về những người sử dụng nó nhiều, nó chắc chắn là những gì người ta sẽ muốn sử dụng trong tình huống này và không phải ở tất cả các khó khăn sau khi tạo ra một. –

2

Tôi sẽ để lại câu trả lời gốc nhưng sai. Cách thích hợp để làm điều này sẽ có một Tomcat VirtualHost:

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

Việc đi bộ qua chính thức tại liên kết ở trên là chính xác những gì tôi đã sử dụng nhiều lần bây giờ. Tôi sẽ không cố gắng đun sôi nó xuống đây.

Khái niệm này giống với một Apache Vhost. Tạo một máy chủ ảo (ví dụ: something.yourtdomain.com) và triển khai ứng dụng web của bạn tới ứng dụng ROOT (/) cho vhost đó và bạn đã sẵn sàng. Bằng cách này, nếu bạn đã có một ứng dụng web ROOT, bạn có thể có một ứng dụng khác tại một miền khác và trước đó sẽ không bị ảnh hưởng. Như Nestor đã đề cập, quy tắc viết lại Apache sẽ không xử lý những thứ như thẻ lib và khung công tác tự động tạo liên kết/hành động biểu mẫu/v.v. cho bạn dựa trên gốc ngữ cảnh. Trong trường hợp này, họ sẽ tạo đúng ngữ cảnh gốc (/).

+2

Trong trường hợp bạn không biết, bạn thực sự có thể rời khỏi ứng dụng của bạn trong thư mục webapps và chỉ cần đặt appBase vào đường dẫn đầy đủ của ứng dụng. --- Ví dụ: \t \t \t – skel625

-1

Sử dụng mod_proxy_ajp thay mod_jk như dưới đây:

<VirtualHost *:80> 
    ServerName domain.be 

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

    ... 

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

    ... 
</VirtualHost> 
+0

Điều đó vẫn không hoạt động nếu Tomcat thực hiện bất kỳ chuyển hướng nào. Nó không thực sự thay đổi vấn đề cơ bản chút nào. Không phải là câu trả lời. – EJP

0

Tiếp theo gợi ý được đưa ra bởi câu trả lời Nestor Urquiza của, tôi quản lý để giải quyết vấn đề này bằng cách định nghĩa thêm Host trong server.xml của tomcat vì như đã nói, yêu cầu j_security_check được trả lời bởi tomcat với một hướng dẫn chuyển tiếp đến trình duyệt mà chắc chắn có chứa tên ngữ cảnh để người dùng cố gắng đăng nhập được 408 lỗi. Vì vậy, một passthrough thực bên trong Apache VirtualHost JkMount /* worker1 chỉ thị là đạt được bằng cách làm cho bối cảnh dự định, một ROOT một.

Apache httpd.conf [và/hoặc bao gồm * conf] file:

<!-- 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 

Vì vậy, để lập bản đồ tất cả các yêu cầu thực hiện để tên miền phụ http://appWelcome.example.org/ trực tiếp đến phụ trách/appWelcome bối cảnh tomcat, các appWelcome bối cảnh phải có địa chỉ với yêu cầu đến http://appWelcome.example.org:8080/

Vì vậy, tệp tomcat server.xml sau đó sẽ mặc riêng Host cho ứng dụng bạn đang muốn hiển thị:.

<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> 

Lưu ý rằng các điều khoản (và bối cảnh selinux nếu được kích hoạt) cần phải được điều chỉnh để bắt chước mặc định Host người như sau:

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

$CATALINA_HOME/appWelcomeBase như $CATALINA_HOME/webapps

ở đâu đến điều này được thực hiện tất cả những gì còn lại để làm là đổi tên và di chuyển kho lưu trữ web appWelcome.war để nó tự động triển khai trong sốđược tạo(thay thế $ CATALINA_HOME bằng giá trị của nó, ví dụ:/var/www/tomcat7):

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

Thì đấy!