Most of the servers have more than one running application on their different ports. You should select the port to visit the application. For example: http://213.248.89.10:7070. The default port of http is 80. I mean if you request http://213.248.89.10, the request is http://213.248.89.10:80. we can have more than one domain on a server but only one application can be run on specified port. So how can we run more than one application and access them without determining any port? The solution is: we can run an web server application on the default port and this web server application should choose the other running application and forward the request to it by requested address. For example a server with ip address of 213.248.89.10 has this applications:
Application Name | port | address |
---|---|---|
A | 7070 | a.com |
B | 6060 | b.com |
C | 5050 | c.com |
we should run an web server application on port 80. Then it should process the request address:
if (requestAddress is a.com) then communicate with port 7070
else if (requestAddress is b.com) then communicate with port 6060
else if (requestAddress is c.com) then communicate with port 5050
Here I am going to do this sample by Apache and Apache tomcat. My sample server(213.248.89.10 IP address) has these running applications:
Application Name | port | ajp port | address | Web Server |
---|---|---|---|---|
- | 80 | - | Apache | |
A | 7070 | 8007 | a.com | Apache Tomcat |
B | 6060 | 8006 | b.com | Apache Tomcat |
C | 5050 | 8005 | c.com | Apache Tomcat |
The connection protocol between Apache and Apache tomcat is ajp13(Apache JServe Protocol). So what is ajp13?
ajp13
The ajp13 protocol is packet-oriented. A binary format was presumably chosen over the more readable plain text for reasons of performance. The web server communicates with the servlet container over TCP connections. To cut down on the expensive process of socket creation, the web server will attempt to maintain persistent TCP connections to the servlet container, and to reuse a connection for multiple request/response cycles.
Once a connection is assigned to a particular request, it will not be used for any others until the request-handling cycle has terminated. In other words, requests are not multiplexed over connections. This makes for much simpler code at either end of the connection, although it does cause more connections to be open at once.
Once the web server has opened a connection to the servlet container, the connection can be in one of the following states:
- Idle
No request is being handled over this connection. - Assigned
The connecton is handling a specific request.
At this point, the servlet container is presumably ready to start processing the request. As it does so, it can send the following messages back to the web server:
- SEND_HEADERS
Send a set of headers back to the browser. - SEND_BODY_CHUNK
Send a chunk of body data back to the browser. - GET_BODY_CHUNK
Get further data from the request if it hasn't all been transferred yet. This is necessary because the packets have a fixed maximum size and arbitrary amounts of data can be included the body of a request (for uploaded files, for example). (Note: this is unrelated to HTTP chunked tranfer). - END_RESPONSE
Finish the request-handling cycle.
Well...
So in my solution any requests should first pass Apache then visit the specified Apache Tomcat
image 1 |
Apache Configuration
I should first configure the Apache to map the request to specified tomcat node.
First I should copy mod_jk.so file to the [Apache root path]/modules path. you can download mod_jk.so here.
Then I should create [Apache root path]conf/workers.properties file and write ajp port specification in it.
# Define 1 real worker named ajp13
worker.list=ajp7,ajp6,ajp5
# Set properties for worker named ajp13 to use ajp13 protocol,
# and run on port 8009
worker.ajp7.type=ajp13
worker.ajp7.host=213.248.89.10
worker.ajp7.port=8007
worker.ajp7.lbfactor=50 worker.ajp7.cachesize=10 worker.ajp7.cache_timeout=600 worker.ajp7.socket_keepalive=1 worker.ajp7.socket_timeout=300 worker.ajp6.type=ajp13 worker.ajp6.host=213.248.89.10 worker.ajp6.port=8006 worker.ajp6.lbfactor=50 worker.ajp6.cachesize=10 worker.ajp6.cache_timeout=600 worker.ajp6.socket_keepalive=1 worker.ajp6.socket_timeout=300 worker.ajp5.type=ajp13 worker.ajp5.host=213.248.89.10 worker.ajp5.port=8005 worker.ajp5.lbfactor=50 worker.ajp5.cachesize=10 worker.ajp5.cache_timeout=600 worker.ajp5.socket_keepalive=1 worker.ajp5.socket_timeout=300
# Load mod_jk module
# Update this path to match your modules location
LoadModule jk_module modules\mod_jk.so
# Where to find workers.properties
# Update this path to match your conf directory location
JkWorkersFile conf\workers.properties
# Where to put jk logs
# Update this path to match your logs directory location
#JkLogFile c:/tomcat/logs/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel info
# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"
<VirtualHost a.com>
# Send everything for context a.com to worker ajp7
JkMount / ajp7
JkMount /* ajp7
</VirtualHost>
<VirtualHost b.com>
# Send everything for context b.com to worker ajp6
JkMount / ajp6
JkMount /* ajp6
</VirtualHost>
<VirtualHost b.com>
# Send everything for context c.com to worker ajp5
JkMount / ajp5
JkMount /* ajp5
</VirtualHost>
#
# This is the main Apache HTTP server configuration file. It contains the
# configuration directives that give the server its instructions.
...
# Various default settings
#Include conf/extra/httpd-default.conf
Include conf/extra/mod_jk.conf
# Secure (SSL/TLS) connections
#Include conf/extra/httpd-ssl.conf
#
# Note: The following must must be present to support
# starting without SSL on platforms with no /dev/random equivalent
# but a statically compiled-in mod_ssl.
#
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
Apache Tomcat configuration
I should just open [Apache Tomcat root]/conf/server.xml file and change the ajp connector tag:
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="7070" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF8" />
<Connector port="8007" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>
</Engine>
</Service>
</Server>
Final step
Just I should restart Apache service and then start Apache Tomcat(s). Now if I request a.com the tomcat on 7070 port will be notified and if I request b.com the tomcat on 6060 port will be notified and so on.
Note: If you test these steps on your client and no domain does not exist, you should define new host name for a.com, b.com and c.com to be mapped to 127.0.0.1 IP. In MS Windows open [windows drive]/Windows/System32/drivers/etc/hosts file then add these lines:
...
127.0.0.1 localhost
127.0.0.1 a.com
127.0.0.1 b.com
127.0.0.1 c.com
...
Enjoy yourselves ...
all rights reserved by Mostafa Rastgar and Programmer Assistant weblog
No comments:
Post a Comment