Recently I have to deploy two Java web applications on a single server (one IP address). Where static content was to be served by Apache Http web server instead of Java application servers. When we have multiple applications deployed on an instance of Tomcat or JBoss we have their URLs something like http://server:port/appA, http://server:port/appB etc. This kind of URLs does not look good when we publish it to external world. So instead of 'http://domainA.tld/appA' we wanted to have URL as 'http://domainA.tld/'. This can be achieved by running applications on different instances of Tomcat / JBoss and fronting them with Apache using virtual hosts.
Running multiple instances of JBoss on a machine with single IP address is a nightmare, while it is much easier to run several Tomcat instances, as one has to change just four ports (8005, 8080, 8443, 8009). An application can be run at root context in Tomcat by adding a line like below, inside <host> element in $TOMCATHOME/conf/server.xml-
<context path="" docbase="appA.war" unpackWAR="false" />
There are pretty decent documentation available on Apache, Tomcat and JBoss' website about their installation and configuration. So I will leave that discussion here itself. Though there is lots of documentation available for Apache virtual hosting also but it takes lots of effort for a newbie to do the configuration and put it in front of application servers. Here I am assuming that Apache Tomcat Connector (mod_jk) is also installed along with Apache web server.
To establish communication between Apache and application server, first we need to define connector workers as shown below-
worker.list=appA,appB
# Define appA
worker.appA.port=9009
worker.appA.host=localhost
worker.appA.type=ajp13
worker.appA.lbfactor=1
# Define appB
worker.appB.port=8009
worker.appB.host=localhost
worker.appB.type=ajp13
worker.appB.lbfactor=1
In the above configuration appA's server's connector is listening on port 9009 and appB's on 8009. This connector port is different from http port (8080 by default for Tomcat). Now define the virtual hosts, this can be done either in Apache's httpd.conf or in a separate file and include that in httpd.conf.
NameVirtualHost *:80
LoadModule jk_module modules/mod_jk.so
# Where to find workers defined above
JkWorkersFile conf/extra/worker.properties
<virtualhost *:80>
ServerAdmin someone@domainA.tld
DocumentRoot "/path/to/the/content"
ServerName domainA.tld
ErrorLog "logs/domainA-error.log"
CustomLog "logs/domainA-access.log" common
JkMount / appA
JkMount /* appA
JkUnMount /static|/* appA
JkLogFile logs/mod_jk_appA.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories
JkRequestLogFormat "%w %V %T"
</virtualhost>
<virtualhost *:80>
ServerAdmin someone@domainB.tld
DocumentRoot "/path/to/the/content"
ServerName domainB.tld
ErrorLog "logs/domainB-error.log"
CustomLog "logs/domainB-access.log" common
JkMount / appB
JkMount /* appB
JkUnMount /static|/* appB
JkLogFile logs/mod_jk_appB.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories
JkRequestLogFormat "%w %V %T"
</virtualhost>
With above configuration all requests to domainA.tld are served by worker appA and domainB.tld is served by worker appB. The 'JkUnMount /static|/* appA' causes any URL like http://domainA.tld/static/* to be served by Apache instead of the application server. As Apache performs far better while serving the static content like images, html, css, java script etc. so it is good to unmount their URLs from the mod_jk worker. Most of the Jk* properties can be defined out of the <virtualhost> element at global level, that will avoid duplicate entries. Though defining them inside <virtualhost> element gives flexibility to have different values for each virtual host. Detailed information about Jk* is available here.
I have tested above configuration with following environment-
- Java: 1.6.0_10
- Tomcat: 6.0.18
- JBoss: 5.0.0.GA
- Apache: 2.2.11
- OS: Fedora 9, Red Hat Enterprise Linux 5 and Windows Vista
27 Comments:
A few years ago I saw someone doing almost the same thing by using Tomcat in a reverse proxy setup with Apache. It was actually quite simple to configure. Have you thought about that?
Hi, is mod_jk still the best way to put an apache server in front of tomcat/jboss. I'm just now upgrading from v3.2.5 to v5.
Thanks,
Brent
brent@efficio.us.com
mod_jk looks a good option to put in front of JBoss. Though using ProxyPass and ProxyReverse thing one can avoid the mod_jk.
whcih to use either mod_jk ProxyPass or ProxyReverse in front of jboss using apache.
what's different between both... performance , security etc
Apache 2.2 with mod_proxy and related module has made mod_jk redundant. Though mod_jk is still better than mod_proxy in load balancing.
Can you possibly share what version of mod_jk you used. I have the following config:
Java: 1.6.0_13
Tomcat: 6.0.18
Apache: 2.2.11
OS: Windows XP
I tried the following two jk modules, but I can't seem to connect from Apache to Tomcat:
- mod_jk-1.2.28-httpd-2.2.3.so
- mod_jk-1.2.27-httpd-2.2.10.so
Thanks.
AG
I used mod_jk-1.2.27-httpd-2.2.6.so on Linux and on Windows it was mod_jk-1.2.27-httpd-2.2.10.so
DocumentRoot "/path/to/the/content"
"/path/to/the/content" what should I give in this path?
is it path from Tomcat server or Apache web server?
and one more, how to access these static content say .js file in application?
Ravi,
DocumentRoot "/path/to/the/content" is the absolute path of the content on disk not relative to Tomcat or Apache. Static content like JS or CSS are just a include in HTML/JSP files, so just write correct URL in the files.
thanks vinod...
still i have one doubt , i hav kept all my javascript files in apache htdocs(C:/apache/htdocs/js) in that js folder i have Example.js , now i want to use this Example.js file in my jsp so what is the url path i have to give?
My apache is running on http://localhost:81 and tomcat is running on http://localhost:8080 . I am able to connect to tomcat through apache and modJk
Suppose your JS and JSP files are accessible using following URLs-
JSP- http://localhost:81/jsp/myPage.jsp
JS- http://localhost:81/js/myScript.js
To include the Javascript in JSP page, you should write something like-
@import url(/js/myScript.js);
Hope this helps.
no vinod am not able to access like this..
JSP- http://localhost:81/jsp/myPage.jsp
JS- http://localhost:81/js/myScript.js
If i request http://localhost:81, at ll directly go to the tomcat (http://localhost:8080) this is my problem, how to get rid of this ? please help me..
See the JkMount and JkUnMount references in the post. You need to unmount the /js URL and get it served by Apache.
Also if required you may need to add something like below in server.xml to run application at root context in Tomcat.
<context path="" docbase="appA.war" unpackWAR="false" />
i have checked, i think am right, but its not working...
VirtualHost localhost:8080>
ServerName localhost
ServerAdmin rbparagi@gmail.com
DocumentRoot "C:/Apache2.2/htdocs"
# All requests go to worker1 by default
JkMount /* ajp13
# Serve html, jpg and gif using httpd
#JkUnMount /*.html ajp13
#JkUnMount /*.jpg ajp13
#JkUnMount /*.gif ajp13
JkUnMount /*.js ajp13
Directory "C:/Apache2.2/htdocs"
# Options Indexes FollowSymLinks MultiViews
Options None
AllowOverride None
Order allow,deny
allow from all
Directory
VirtualHost
this is my configuration..
is it work?
and how to give JkMount and Jkunmount ? can u give me one example? am new to this so..
Not sure if 'JkUnMount /*.js ajp13' will work or not. I kept all static content in a different directory (say static) and then unmounted that like below-
JkUnMount /static|/* appB
Also you need to have two JkMount directives instead of one-
JkMount / appB
JkMount /* appB
Why don't you give it a try on same pattern as shown in this blog entry, that may help in narrowing down to the root cause of the problem.
ok i ll check..
where u kept that static folder?
in apache or in tomcat or independent of these two folders?
And one more what is appB ? is it war file?
static goes under Apache DocumentRoot. Yes appB is a war file.
still i am not getting..
i am thinking i need to give url pattern using RewriteRule . am i right?
hi vinod..
i am able to connect to C:/apache-tomcat-6.0.18/webapps/ROOT instead of C:\Apache2.2\htdocs..
could u plz help me how to go to this C:\Apache2.2\htdocs ?
how to configure the static content like css,js and dynamic content like jsp using apache + weblogic
Just unmount the URLs, which serve the static content as shown in the configuration in the post-
JkUnMount /static|/* appB
Do not forget to store the static content in a directory, which is accessible to Apache.
Hi Vinod,
I hope you can help you in this problem.
I have Fedora 13, jdk 1.6, jboss 5.0 and eclipse 3.5. Right now everything seems to be working fine but I have to include a separate Tomcat (tomcat 6) in this environment. i.e. I need to disable the tomcat instant that coming with Jboss and need to start a separate tomcat. Also need to use Apache to serve the static contents. Could you please tell me how I can disable the tomcat instant in Jboss and start a separate tomcat server?
Thanks, Vinod.
Please share some sample applications to deploy on Tomcat and Jboss 5.0.1 I cant find any on google even applications that worked on JBoss 4.2.3 not working with JBoss 5
@Nikhil,
See here http://blog.vinodsingh.com/2008/09/jax-ws-web-service-and-jboss.html
http://blog.vinodsingh.com/2008/09/building-jax-ws-web-service.html
there is an sample application attached there, I believe that should work on both Tomcat and JBoss.
Hi vinod ... i followed your advice but could not get static content served from apache. Do I need to do some configuration changes at tomcat as well. The images folder was in /webapps/appB/ but I removed it since I wanted to serve the images from apache. I put the images folder under my document root as mentioned below but still didn't work out. Can you tell what is wrong in this. I have solaris system to play with apache 2.2 and tomcat 6.0.18.
ServerName www.xyz.com
ServerAdmin webmaster@abc.com
DocumentRoot /opt/apache/www/fundoo/foo
# To turn off rewrite logging is 0, 3 is debug
RewriteLogLevel 0
RewriteEngine off
RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]
#Alias /appB /opt/apache/www/fundoo/foo
JkMount /appB/*.gft balancer
JkMount /appB/*.jsp balancer
JkMount /appB/* balancer
JkUnMount /images/* appB
#JkUnMount /*.png balancer
#JkUnMount /*.jpg balancer
#JkUnMount /*.gif balancer
#JkUnMount /*.js balancer
Hi Vinod,
i have some requirement for configuring apache http server 2.0.64 with JBOSS 4.2.3.
I have installed JBOSS with port:8088 and Apache http with port: 8080
Both are up and running.
Now
--->i have downloaded the mod_jk.so and added in the below path:
Apache/modules
--->I have created a new file "mod-jk.conf" and added under Apache/conf with the below content.
mod-jk.conf --->
LoadModule jk_module modules/mod_jk.so
JkWorkersFile conf/workers.properties
JkShmFile logs/mod_jk.shm
JkLogFile logs/mod_jk.log
JkLogLevel info
JkMount /App1/* worker1
--->I have added the below file andd added the line in the last line of the file "Include conf/mod-jk.conf" Apache/conf/httpd.conf
--->I have created workers.properties inside apache/conf folder with below content.
worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009
Now both the ervers are up and running successfully. But how can i know that these 2 are connected and configured properly.
Thanks in Advance,
Suresh.
suvunnam@in.ibm.com
@Suresh,
Try to access the application via Apache (port 80) that will let you know whether integration is working or not.
Post a Comment