Thursday, June 26, 2014

How to configure a Tomcat cluster on Ubuntu

http://xmodulo.com/2014/06/configure-tomcat-cluster-ubuntu.html

Apache Tomcat is the most popular open-source Java web server. If your web site is expecting more traffic as your business grows, a single instance of Tomcat will probably not scale with the growing traffic. In that case, you might be thinking to run Tomcat in a "clustered" environment, where web server workload is distributed to multiple Tomcat instances.
In this article I will show you how to configure a Tomcat cluster with load balancing and session replication. Before we delve into the details about the setup, we want to clarify some of the terms we will be using in this tutorial.

Terminology

Load balancing: When HTTP requests are received by a front-end server (often called "load balancer", "proxy balancer" or "reverse proxy"), the front-end server distributes the requests to more than one "worker" web servers in the backend, which actually handle the requests. Load balancing can get rid of a single point of failure in the backend, and can achieve high availability, scalability and better resource optimization for any web service.
Session replication: Session replication is a mechanism to copy the entire state of a client session verbatim to two or more server instances in a cluster for fault tolerance and failover. Typically, stateful services that are distributed are capable of replicating client session states across different server instances in a cluster.
Cluster: A cluster is made up of two or more web server instances that work in unison to transparently serve client requests. Clients will perceive a group of server instances as a single entity service. The goal of the cluster is to provide a highly available service for clients, while utilizing all available compute resources as efficiently as possible.

Requirements

Here are the requirements for setting up a Tomcat cluster. In this tutorial, I assume there are three Ubuntu servers.
  • Server #1: Apache HTTP web server with mod_jk (for proxy balancer)
  • Server #2 and #3: Java runtime 6.x or higher and Apache Tomcat 7.x (for worker web server)
Apache web server is acting as a proxy balancer. Apache web server is the only server visible to clients, and all Tomcat instances are hidden from clients. With mod_jk extension activated, Apache web server will forward any incoming HTTP request to Tomcat worker instances in the cluster.
In the rest of the tutorial, I will describe step by step procedure for configuring a Tomcat cluster.

Step One: Install Apache Web Server with mod_jk Extension

Tomcat Connectors allows you to connect Tomcat to other open-source web servers. For Apache web server, Tomcat Connectors is available as an Apache module called mod_jk. Apache web server with mod_jk turns a Ubuntu server into a proxy balancer. To install Apache web server and mod_jk module, use the following command.
$ sudo apt-get install apache2 libapache2-mod-jk

Step Two: Install JDK and Apache Tomcat

The next step is to install Apache Tomcat on the other two Ubuntu servers which will actually handle HTTP requests as workers. Since Apache Tomcat requires JDK, you need to install it as well. Follow this guide to install JDK and Apache Tomcat on Ubuntu servers.

Step Three: Configure Apache mod_jk on Proxy Balancer

On Ubuntu, the mod_jk configuration file is located in /etc/apache2/mods-enabled/jk.conf. Update this file with the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    # We need a workers file exactly once
    # and in the global server
    JkWorkersFile /etc/libapache2-mod-jk/workers.properties
    # JK error log
    # You can (and should) use rotatelogs here
    JkLogFile /var/log/apache2/mod_jk.log
    # JK log level (trace,debug,info,warn,error)
    JkLogLevel info
    JkShmFile /var/log/apache2/jk-runtime-status
    JkWatchdogInterval 60
    JkMount /*  loadbalancer
    JkMount /jk-status jkstatus
    # Configure access to jk-status and jk-manager
    # If you want to make this available in a virtual host,
    # either move this block into the virtual host
    # or copy it logically there by including "JkMountCopy On"
    # in the virtual host.
    # Add an appropriate authentication method here!
    /jk-status>
            # Inside Location we can omit the URL in JkMount
            JkMount jk-status
            Order deny,allow
            Deny from all
            Allow from 127.0.0.1
    </Location>
    /jk-manager>
            # Inside Location we can omit the URL in JkMount
            JkMount jk-manager
            Order deny,allow
            Deny from all
            Allow from 127.0.0.1
    </Location>
</IfModule>
In order to make the above configuration work with multiple Tomcat instances, we have to configure every Tomcat worker instance in /etc/libapache2-mod-jk/workers.properties. We assume that the IP addresses of the two worker Ubuntu machines are 192.168.1.100 and 192.168.1.200.
Create or edit etc/libapache2-mod-jk/workers.properties with the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
worker.list=loadbalancer,jkstatus
# Configure Tomcat instance for 192.168.1.100
worker.tomcat1.type=ajp13
worker.tomcat1.host=192.168.1.100
worker.tomcat1.port=8081
# worker "tomcat1" uses up to 200 sockets, which will stay no more than
# 10 minutes in the connection pool.
worker.tomcat1.connection_pool_size=200
worker.tomcat1.connection_pool_timeout=600
# worker "tomcat1" will ask the operating system to send a KEEP-ALIVE
# signal on the connection.
worker.tomcat1.socket_keepalive=1
# Configure Tomcat instance for 192.168.1.200
worker.tomcat2.type=ajp13
worker.tomcat2.host=192.168.1.200
worker.tomcat2.port=8082
# worker "tomcat2" uses up to 200 sockets, which will stay no more than
# 10 minutes in the connection pool.
worker.tomcat2.connection_pool_size=200
worker.tomcat2.connection_pool_timeout=600
# worker "tomcat2" will ask the operating system to send a KEEP-ALIVE
# signal on the connection.
worker.tomcat2.socket_keepalive=1
worker.jkstatus.type=status
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=tomcat1,tomcat2

Step Four: Configure Tomcat Instances

Edit /opt/apache-tomcat-7.0.30/conf/server.xml for Tomcat instance on 192.168.1.100 with the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    "Catalina" defaultHost="192.168.1.100” jvmRoute="tomcat1">
    "org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
    "org.apache.catalina.ha.session.DeltaManager"
        expireSessionsOnShutdown="false"
        notifyListenersOnReplication="true"/>
    "org.apache.catalina.tribes.group.GroupChannel">
        "org.apache.catalina.tribes.transport.ReplicationTransmitter">
            "org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
        </Sender>
        "org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto"        port="4000" autoBind="100" selectorTimeout="5000" maxThreads="50"/>
    "org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
    "org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
    </Channel>
    "org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
    "org.apache.catalina.ha.session.JvmRouteBinderValve"/>
    "org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
    "org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
Edit /opt/apache-tomcat-7.0.30/conf/server.xml for Tomcat instance on 192.168.1.200 with the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    "Catalina" defaultHost="192.168.1.200” jvmRoute="tomcat2">
    "org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
    "org.apache.catalina.ha.session.DeltaManager"
        expireSessionsOnShutdown="false"
        notifyListenersOnReplication="true"/>
    "org.apache.catalina.tribes.group.GroupChannel">
        "org.apache.catalina.tribes.transport.ReplicationTransmitter">
            "org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
        </Sender>
     
        "org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto"        port="4000" autoBind="100" selectorTimeout="5000" maxThreads="30"/>
    "org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
    "org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
    </Channel>
    "org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
    "org.apache.catalina.ha.session.JvmRouteBinderValve"/>
    "org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
    "org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

Step Five: Test a Tomcat Cluster

Tomcat Connectors has a special type of worker, the so-called status worker. The status worker does not forward requests to Tomcat instances. Instead, it allows one to retrieve status and configuration information at run-time, and even to change many configuration options dynamically. You can monitor the Tomcat cluster by accessing this status worker, which can be done simply by going to http:///jk-status on a web browser.

No comments:

Post a Comment