Sunday, 20 March 2016

Virtual hosting in Apache server


Scenario
If we have big organization and each department want to host their website in different machine, then how to achieve the virtual host concept, so these websites are accessed locally with different local IP address.

We have 2 choices :
1. Purchase as many public address 
- OR -
2. Put one server front  and delegate these request.
Put Apache httpd web server in front of all department servers, so only one public IP is enough.
All domain DNS entries are pointed to Apache httpd server, then Apache server delegates these request to corresponding tomcat server.

 

















How Apache httpd web server communicate to Tomcat ?

Ports binded when we start tomcat : 
1. shutdown port
2. http connector port
3. https connector port (optional)
4. ajp port
The port configuration are stored in $CATALINA_HOME/conf/server.xml file.
We can change the ports when its necessary.


What' s AJP port ?
Here, AJP(Apache JServ Protocol)  is a binary protocol that can proxy inbound requests from a web server through to an application server that sits behind the web server.

Apache httpd web server communicate to Tomcat sever through AJP protocol.
When we install Apache httpd server, It don't have inbuilt capability to support ajp protocol, so we need mod_jk module.
Its add the ajp support to Apache httpd server.


Steps to implement Virtual Host concept

Install Apache httpd Web Server
Install mod_jk connector
Configure JK connector
Configure Apache httpd server to apply virtual host concepts

Prerequisite : We already installed Tomcat in different departments and deployed the application and works fine.

Step 1. Install Apache httpd web server
We can install Apache web server in two ways : 
 a. Binary module - Install Apache httpd server from distribution package manager (either apt-get or yum)
 b. From Source - Download the source code and then compile and install

Step 2. Install mod_jk connector
To add ajp support to server, download the mod_jk connector module from here. Extract it and install it.
Now, mod_jk.so files will be created on modules directory in apache installed location (/usr/local/apache/modules)



Step 3. Configure mod_jk connector
This step have 2 sub step  :
  a. Create workers.properties file
  b. Load and configure the JK connector module in apache httpd.conf file

Create workers.properties file 
mod_jk connector is ready, but this connector is works based on configuration file so we need to create configuration file called workers.properties file.
This file syntax is key=value pair, here we define the workers. i.e all department tomcat hosts IP address and ajp port for corresponding tomcat.
Here, entry format is worker.name.property=value

Example,
worker.list=name
worker.name.type=ajp13
worker.name.port=ajp-port
worker.name.host=tomcat-IP-address

Here, worker.list key have all workers name separated by comma.
type = Type of the worker. we use ajp13 version 
port= The ajp port (not http port ) of that server
host= IP address or host name of tomcat server

workers.properties
worker.list=department1,department2,department3
worker.department1.type=ajp13
worker.department1.port=5000
worker.department1.host=192.168.5.10
worker.department2.type=ajp13
worker.department2.port=5000
worker.department2.host=192.168.6.10
worker.department3.type=ajp13
worker.department3.port=5000
worker.department3.host=192.168.7.10


Add Entry in httpd.conf
Apache httpd server is installed, mod_jk module is installed and workers.properties file is created but these 3 are isolated.
We put together, we need to configure the httpd server.
Find the conf/httpd.conf file in Apache installed location and add these following entries to it
LoadModule    jk_module  modules/mod_jk.so
JkWorkersFile conf/workers.properties
JkLogFile     logs/mod_jk.log
JkLogLevel    emerg
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkOptions     +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat     "%w %V %T"
Here,
LoadModule : Load mod_jk shared module to Apache httpd server (enable the mod_jk module)
JkWorkersFile : Specify the workers.properties file location
All others are logging system of mod_jk.


Delegate httpd to Tomcat
Now, we inform to Apache httpd server how delegate the request to corresponding server.
JkMount  /department1* department1
JkMount  /department2* department2
JkMount  /department3* department3

Here,
JkMount : specifies if URL have /department1* pattern then that request delegate to department1 worker (that worker IP address and port is specified in workers.properties file)
We changed /etc/hosts file, so that all web site domain pointed to apache httpd web server.

If we access http: //www.geniusprog.com/department1/index.html, how Apache httpd server process the request.
Its perfectly called correct tomcat server and we got right response.


Additional reqirement #1
I don't want the my URL like  http://www.geniusprog.com/department1/index.html
I want the my URL like  http://www.geniusprog.com/index.html  ;

Solution
Remove the department1 from my URL but department1 string is very important in URL because JkMount is works based on this matching string only.



Additional requirement #2
http://www.geniusprog.com/department1/index.html is for first tomcat and second department have domain   http://www.shaanweb.com then access second tomcat we use URL : http://www.shaanweb.com/department2/index.html but same time when we use URL http://www.shaanweb.com/department1/index.html then we access first tomcat dat. So, 
because both these URL have department1 keyword, so JkMount is works based on these keyword. As the Result wrong interpretation.

Solution
Virtual Host in Apache httpd Server
We need to add conditional JkMount. For example, geniusprog.com domain asks the whereare paths like department1, department2 we need to search in that tomcat only, not other place.
To add this conditioned we add virtual host entries. 

Add virtual host entry in httpd.conf file
Listen 80
NameVirtualHost *:80
<VirtualHost *:80>   
  ServerName www.geniusprog.com   
  JkMount  /department1* department1
</VirtualHost>
<VirtualHost *:80>   
  ServerName www.shaanweb.com   
  JkMount  /department2* department1
</VirtualHost>
Here,
ServerName - Domain name of the server

If http://www.shaanweb.com/department1/index.html URL is like this now, server matches the Server Name.
Here, it matches 2nd virtual host entry. There are single JkMount entry is there in 2nd Virtual-Host and there no matching department1 string.  

JkMount  /department2* department1
as the result 404 error page is responded.
Its works good.



Additonal requirement #3
Now, My URL is http://www.geniusprog.com/department1/index.html here i don't want department1 path in my URL.

Solution
Use mod_rewrite engine
Listen 80
NameVirtualHost *:80
<VirtualHost *:80>   
  ServerName www.geniusprog.com
  RewriteEngine on
  RewriteLog logs/apache-mod_rewrite
  RewriteRule ^/(.*)$ /department1/$1 [L,PT]     
  JkMount  /* <dept_name>
</VirtualHost>

Here,
RewriteEngine on - Turn on the Rewrite module
RewriteRule ^/(.*)$ /department1/$1 [L,PT]  - ^/(.*)$ matches any string, it capture the value to $1 and change the URL to/department1/$1 

Example :
http://www.geniusprog.com/index.html : ^/(.*)$; matches index.html it capture to $1 and replaced to /department1/$1==> /department1/index.html


Rewrite is happen before delegate the request to Tomcat, so we change the URL transparently to browser.
Now, client (browser) just send http://www.geniusprog.com is enough to access the Department 1 Tomcat.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.