Virtual hosting, load balancing and clustering.
The Big Picture
Virtual Hosting
Example: we will install 3 virtual hosts called: localhost for www.mytcl.com, localhost2 for www.mytte.com, and localhost3 for www.mypmu.com
server.xml
Add below statement to a host entry localhost2 of the $TOMCAT_HOME/conf/server.xml file:
<Host name="localhost2" debug="0" appBase="webapp2"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Alias>www.mytte.com</Alias>
<Alias>mytte.com</Alias>
</Host>
Repeat the above steps to add a host entry localhost3 of the $TOMCAT_HOME/conf/server.xml file:
<Host name="localhost3" debug="0" appBase="webapp3"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Alias>www.mypmu.com</Alias>
<Alias>mypmu.com</Alias>
</Host>
ROOT.xml
Add a configuration file for the localhost2 (www.mytte.com)
Step 1: mkdir $TOMCAT_HOME/conf/Catalina/localhost2
Step 2: copy $TOMCAT_HOME/conf/Catalina/localhost/ROOT.xml to $TOMCAT_HOME/conf/Catalina/localhost2/ROOT.xml
Step 3: modify "Context path" of $TOMCAT_HOME/conf/Catalina/localhost2/ROOT.xml
as below:
< Context path="" debug="0" reloadable="true"
cookies="true" crossContext="false" privileged="false" >
Repeat above steps to add a configuration file for the localhost3 (www.mypmu.com)
Step 1: mkdir $TOMCAT_HOME/conf/Catalina/localhost3
Step 2: copy $TOMCAT_HOME/conf/Catalina/localhost/ROOT.xml to $TOMCAT_HOME/conf/Catalina/localhost3/ROOT.xml
Step 3: modify "Context path" of $TOMCAT_HOME/conf/Catalina/localhost3/ROOT.xml
as below:
< Context path="" debug="0" reloadable="true"
cookies="true" crossContext="false" privileged="false" >
A new host
Add a new host of localhost2 (www.mytte.com)
Step 1: Create a new folder $TOMCAT_HOME/webapp2/ROOT
Step 2: Copy all the content of $TOMCAT_HOME/webapp/ROOT to $TOMCAT_HOME/webapp2/ROOT
Step 3: Edit $TOMCAT_HOME/webapp2/ROOT/WEB-INF/web.xml modify the company_id to mytte.com
Step 4: Create a new folder $TOMCAT_HOME/webapp2/tunnel
Step 5: Copy all the content of $TOMCAT_HOME/webapps/tunnel to /webapp2/tunnel
Repeat above steps to add a new host of localhost3 (www.mypmu.com)
Step 1: Create a new folder $TOMCAT_HOME/webapp3/ROOT
Step 2: Copy all the content of $TOMCAT_HOME/webapps/ROOT to $TOMCAT_HOME/webapp3/ROOT
Step 3: Edit $TOMCAT_HOME/webapp3/ROOT/WEB-INF/web.xml modify the company_id to mypmu.com
Step 4: Create a new folder $TOMCAT_HOME/webapp3/tunnel
Step 5: Copy all the content of $TOMCAT_HOME/webapp/tunnel to /webapp3/tunnel
hosts configuration in OS environment
Step 1: hosts
In Windows, modify c:/windows/system32/drivers/etc/hosts as below:
127.0.0.1 localhost www.mytcl.com
127.0.0.1 localhost2 www.mytte.com
127.0.0.1 localhost3 www.mypmu.com
In Linux, modify /etc/hosts as below:
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost.localdomain localhost2
127.0.0.1 localhost.localdomain localhost3
Step 2: In Linux, check /etc/host.conf like below:
order hosts,bind
Step 3: In Linux, check /etc/nsswitch.conf like below:
hosts: files nisplus nis dns
Shared resources
Shared resources at $TOMCAT_HOME/common/lib/ext
Step 1: Move all files of $TOMCAT_HOME/liferay/WEB-INF/lib except
util-taglib.jar to $TOMCAT_HOME/common/lib/ext
Step 2: And delete duplicated files of $TOMCAT_HOME/webapp2/ROOT/WEB-INF/lib
except util-taglib.jar
Repeat step 2 to delete duplicated files of $TOMCAT/webapp3/ROOT/WEB-INF/lib/except util-taglib.jar
Virtual hosting is done
Step 1: In Linux, change directory to $TOMCAT_HOME/tomcat/bin and run startup.sh
Step 2: browse the results at the same machine: http://localhost:8080, http://localhost2:8080 and http://localhost3:8080
Step 3: If domains are forward to the ip address of the machine, users may browse http://www.mytcl.com:8080, http://www.mytte.com:8080 and http://www.mypmu.com:8080
Tomcat Clustering
server.xml
Uncommend the cluster element in $TOMCAT_HOME/conf/server.xml:
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true"
notifyListenersOnReplication="true">
<Membership
className="org.apache.catalina.cluster.mcast.McastService"
mcastAddr="228.0.0.4"
mcastPort="45564"
mcastFrequency="500"
mcastDropTime="3000"/>
<Receiver
className="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4001"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>
<Sender
className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
replicationMode="pooled"
ackTimeout="15000"
waitForAck="true"/>
<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
</Cluster>
<distributable/>
Make user your web.xml has the <distributable/> element or set at your <Content distributable=”true” />
Step 1: For localhost of www.mytcl.com:
Add <distributable/> between <web-app> into $TOMCAT_HOME/webapps/ROOT/WEB-INF/web.xml:
<web-app>
<distributable/>
<context-param>
<param-name>company_id</param-name>
<param-value>liferay.com</param-value>
</context-param>
. . .
</web-app>
Step 2: Repeat step 2.2.1 to localhost2 of www.mytte.com, add <distributable/> into $TOMCAT_HOME/webapp2/ROOT/WEB-INF/web.xml
Step 3: Repeat step 2.2.1 to localhost3 of www.mypmu.com, add <distributable/> into $TOMCAT_HOME/webapp2/ROOT/WEB-INF/web.xml
Clone tomcat
Copy all content of directory $TOMCAT_HOME to another tomcat2
In Linux:
cp -dpr tomcat tomcat2
Port numbers
Change port numbers of tomcat2/conf/server.xml in order to make difference from the previous Tomcat:
<Server port="8006" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
<!-- Global JNDI resources -->
<GlobalNamingResources>
<Environment name="simpleValue" type="java.lang.Integer" value="30"/>
<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="8081" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8444" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true"
URIEncoding="UTF-8" />
<Connector port="8010"
enableLookups="false" redirectPort="8444" protocol="AJP/1.3"
URIEncoding="UTF-8" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm02">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Alias>www.mytcl.com</Alias>
<Alias>mytcl.com</Alias>
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true"
notifyListenersOnReplication="true">
<Membership
className="org.apache.catalina.cluster.mcast.McastService"
mcastAddr="228.0.0.4"
mcastPort="45564"
mcastFrequency="500"
mcastDropTime="3000"/>
<Receiver
className="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4004"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>
<Sender
className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
replicationMode="pooled"
ackTimeout="15000"
waitForAck="true"/>
<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
</Cluster>
</Host>
</Engine>
</Service>
</Server>
Clustering in multiple hosting
Add hosts for localhost2 of www.mytte.com and localhost3 of www.mypmu.com into tomcat2/conf/server.xml. Remember to make tcpListenPort difference from each other:
<Host name="localhost3" debug="0" appBase="webapp3"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Alias>www.mypmu.com</Alias>
<Alias>mypmu.com</Alias>
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true"
notifyListenersOnReplication="true">
<Membership
className="org.apache.catalina.cluster.mcast.McastService"
mcastAddr="228.0.0.4"
mcastPort="45564"
mcastFrequency="500"
mcastDropTime="3000"/>
<Receiver
className="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4006"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>
<Sender
className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
replicationMode="pooled"
ackTimeout="15000"
waitForAck="true"/>
<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
</Cluster>
</Host>
<Host name="localhost2" debug="0" appBase="webapp2"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Alias>www.mytte.com</Alias>
<Alias>mytte.com</Alias>
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true"
notifyListenersOnReplication="true">
<Membership
className="org.apache.catalina.cluster.mcast.McastService"
mcastAddr="228.0.0.4"
mcastPort="45564"
mcastFrequency="500"
mcastDropTime="3000"/>
<Receiver
className="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4005"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>
<Sender
className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
replicationMode="pooled"
ackTimeout="15000"
waitForAck="true"/>
<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
</Cluster>
</Host>
Route in Linux
If the cluster dosen't work under linux with two nodes at two boxes,
Check the following:
1) Is your network interface enabled for multicast? ifconfig eth0 MULICAST
2) Exists a multicast route to your network interface? My settting is: route add -host 228.0.0.4 gw 192.168.10.10 dev eth0
3) Is your firewall active? Then check if that multicast port is on your UDP open list and the receiver TCP port is also open for both machines!
My fair share
Finally, you can start both tomcat machines. You should now be able to see in their logs and that they are communicating as a cluster (example is http://192.168.10.11:8080 and http://192.168.10.12:8081)
And you may check their session replication by using the below test.jsp:
<%@ page contentType="text/html; charset=UTF-8" import="java.util.*"%>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info: <%out.print(request.getLocalAddr() + " : " + request.getLocalPort());%>
<%
out.println(" ID " + session.getId());
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value);
}
%>
<form action="test.jsp" method="POST">
Name:<input type=text size=20 name="dataName">
Value:<input type=text size=20 name="dataValue">
<input type=submit>
</form>
</body>
</html>
Reference
http://tomcat.apache.org/tomcat-5.5-doc/cluster-howto.html
http://tomcat.apache.org/faq/cluster.html
http://www.theserverside.com/tt/articles/article.tss?l=ClusteringTomcat
Load Balancing
Tomcat doesn’t provide the failover capability to redirect any incoming requests to the next available server in case one of the cluster nodes goes down. Hence a load balancer takes care of workload balance and failover.
There is two popular load balancers in open source market:
Solution 1: Apache + mod_jk
(Reference: http://howtoforge.com/high_availability_loadbalanced_apache_cluster)
Solution 2: Pen is a load balancer for "simple" tcp based protocols such as http or smtp. It allows several servers to appear as one to the outside and automatically detects servers that are down and distributes clients among the available servers. This gives high availability and scalable performance.
(Reference: http://siag.nu/pen/)
The difference between Apache+mod_jk and Pen is that installation and operation of Pen is much more simple than Apache+mod_jk.
Download
Download website: http://siag.nu/pub/pen/pen-0.17.1.tar.gz
Unzip files:
tar zxvf pen-0.17.1.tar.gz
Installation
For Linux, type:
./configure
make
make install
For Windows, you have just downloaded it from http://siag.nu/pub/pen/pen-0.17.1.exe
Running
The command to run the load balancer is as follows:
pen -f -a -d -w localhost:80 192.168.10.11:8080 192.168.10.12:8081
The following is the explanation of above command-line parameter used to launch the load balancer.
-w: Use weight algorithm for load balancing
-a: Prints the data sent back and forth in ASCII format
-f: Stay in foreground
-d: Enable debug mode
Reference
http://siag.nu/pen/
http://siag.nu/pen/vrrpd-linux.shtml
Database Clustering
Sequoia is an open source database clustering middleware that allows any Java application to transparently access a cluster of databases through JDBC.
The following example will be shown Liferay and Sequoia working together, we use HSQLDB as the database sample.
Installation
Step 1: Download sequoia-2.10.2-bin.zip from http://sequoia.continuent.org
Step 2: Unzip sequoia-2.10.2-bin.zip to your favourite directory (example: /home/brian/sequoia)
Step 3: Set up environment:
In Linux:
export SEQUOIA_HOME=/home/brian/sequoia
export CLASSPATH_XTRAS=/home/brian/sequoia/3rdparty/hsqldb/lib/hsqldb.jar
In Windows:
set SEQUOIA_HOME=C:\home\brian\sequoia
set CLASSPATH_XTRAS=C:\sequoia\3rdparty\hsqldb\lib\hsqldb.jar
HSQLDB schema
Step 1: Bugfix of Sequoia for HSQLDB
Modify file: $SEQUOIA_HOME/lib/octopus/xml/conf/HypersonicSQLConf.xml
Bugfix 1: Add BOOLEAN between tag “SQLType” like below:
<SQLType>
<BOOLEAN javaType="java.lang.Boolean">BOOLEAN</BOOLEAN>
</SQLType>
Bugfix 2: Modify BOOLEAN between tag “JDBCType” like below:
<JDBCType>>
<BOOLEAN>BOOLEAN</BOOLEAN>
</JDBCType>
Step 2: OctopusDBVendors.xml
Modify file $SEQUOIA_HOME/lib/octopus/xml/conf/OctopusDBVendors.xml
Keep below databases, others may be commented.
<Vendor name="Csv">CsvConf.xml</Vendor>
<Vendor name="HypersonicSQL">HypersonicSQLConf.xml</Vendor>
Step 3: Virtual databases of Liferay
mkdir $HOME/hsqldb1
cp $TOMCAT_HOME/bin/test.*
cd $HOME/hsqldb1
java -cp hsqldb.jar org.hsqldb.Server -port 9001
mkdir $HOME/hsqldb2
cp $TOMCAT_HOME/bin/test.* $HOME/hsqldb2
cd $HOME/hsqldb2
java -cp hsqldb.jar org.hsqldb.Server -port 9002
Step 4: Recovery log database of Sequoia
mkdir $HOME/hsqldb3
cp $SEQUOIA_HOME/3rdparty/hsqldb/data/test.* $HOME/hsqldb3
cd $HOME/hsqldb3
java -cp hsqldb.jar org.hsqldb.Server -port 9003
Step 5: It is an option to repeat step 1 to step 3 to create virtual databases from port 9004 to 9006 similarly
Step 6: Sequoia is flexible to distribute all databases to different machines, see above diagram:
Controller 1 is assigned to 192.168.10.19
Database 1 is assigned to 192.168.10.13
Database 2 is assigned to 192.168.10.14
Recovery log 1 is assigned to 192.168.10.15
Controller 2 is assigned to 192.168.10.20
Database 3 is assigned to 192.168.10.16
Database 4 is assigned to 192.168.10.17
Recovery log 2 is assigned to 192.168.10.18
Step 1: Create controller file $SEQUOIA_HOME/config/controller/liferayController1.xml as belows:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE SEQUOIA-CONTROLLER PUBLIC "-//Continuent//DTD SEQUOIA-CONTROLLER 2.10.2//EN" "[http://sequoia.continuent.org/dtds/sequoia-controller-2.10.2.dtd">]
<SEQUOIA-CONTROLLER>
<Controller ipAddress="192.168.10.19" port="25322">
<JmxSettings>
<RmiJmxAdaptor port="1090"/>
</JmxSettings>
<VirtualDatabase configFile="liferayVDB1.xml" virtualDatabaseName="lportal" autoEnableBackends="true"/>
</Controller>
</SEQUOIA-CONTROLLER>
Step 2: Repeat step 1 to create another controller $SEQUOIA_HOME/config/controller/liferayController2.xml as belows:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE SEQUOIA-CONTROLLER PUBLIC "-//Continuent//DTD SEQUOIA-CONTROLLER 2.10.2//EN" "[http://sequoia.continuent.org/dtds/sequoia-controller-2.10.2.dtd">]
<SEQUOIA-CONTROLLER>
<Controller ipAddress="192.168.10.20" port="25323">
<JmxSettings>
<RmiJmxAdaptor port="1091"/>
</JmxSettings>
<VirtualDatabase configFile="liferayVDB2.xml" virtualDatabaseName="lportal" autoEnableBackends="true"/>
</Controller>
</SEQUOIA-CONTROLLER>
Step 1: Create virtual database file $SEQUOIA_HOME/config/virtualdatabase/liferayVDB1.xml as below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE SEQUOIA PUBLIC "-//Continuent//DTD SEQUOIA 2.10.2//EN" "[http://sequoia.continuent.org/dtds/sequoia-2.10.2.dtd">]
<SEQUOIA>
<VirtualDatabase name="lportal">
<Distribution>
<MessageTimeouts/>
</Distribution>
<Backup>
<Backuper backuperName="Octopus"
className="org.continuent.sequoia.controller.backup.backupers.OctopusBackuper"
options="zip=true"/>
</Backup>
<AuthenticationManager>
<Admin>
<User username="admin" password="adminPassword"/>
</Admin>
<VirtualUsers>
<VirtualLogin vLogin="user" vPassword="userPassord"/>
</VirtualUsers>
</AuthenticationManager>
<DatabaseBackend name="database1" driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:hsql://192.168.10.13:9001" connectionTestStatement="call now()">
<ConnectionManager vLogin="user" rLogin="sa" rPassword="">
<VariablePoolConnectionManager initPoolSize="10" minPoolSize="5" maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
</ConnectionManager>
</DatabaseBackend>
<DatabaseBackend name="database2" driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:hsql://192.168.10.14:9002" connectionTestStatement="call now()">
<ConnectionManager vLogin="user" rLogin="sa" rPassword="">
<VariablePoolConnectionManager initPoolSize="10" minPoolSize="5" maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
</ConnectionManager>
</DatabaseBackend>
<RequestManager>
<RequestScheduler>
<RAIDb-1Scheduler level="passThrough"/>
</RequestScheduler>
<LoadBalancer>
<RAIDb-1>
<WaitForCompletion policy="first"/>
<RAIDb-1-LeastPendingRequestsFirst/>
</RAIDb-1>
</LoadBalancer>
<RecoveryLog driver="org.hsqldb.jdbcDriver"
url="jdbc:hsqldb:hsql://192.168.10.15:9003" login="sa" password="">
<RecoveryLogTable tableName="RECOVERY" logIdColumnType="BIGINT NOT NULL"
vloginColumnType="VARCHAR NOT NULL" sqlColumnType="VARCHAR NOT NULL"
extraStatementDefinition=",PRIMARY KEY (log_id)"/>
<CheckpointTable tableName="CHECKPOINT"
checkpointNameColumnType="VARCHAR NOT NULL"/>
<BackendTable tableName="BACKEND"
databaseNameColumnType="VARCHAR NOT NULL"
backendNameColumnType="VARCHAR NOT NULL"
checkpointNameColumnType="VARCHAR NOT NULL"/>
<DumpTable tableName="DUMP" dumpNameColumnType="VARCHAR NOT NULL"
dumpDateColumnType="TIMESTAMP"
dumpPathColumnType="VARCHAR NOT NULL"
dumpFormatColumnType="VARCHAR NOT NULL"
checkpointNameColumnType="VARCHAR NOT NULL"
backendNameColumnType="VARCHAR NOT NULL"
tablesColumnType="VARCHAR NOT NULL"/>
</RecoveryLog>
</RequestManager>
</VirtualDatabase>
</SEQUOIA>
Step 2: Repeat step 1 to create another virtual database file $SEQUOIA_HOME/config/virtualdatabase/liferayVDB2.xml as below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE SEQUOIA PUBLIC "-//Continuent//DTD SEQUOIA 2.10.2//EN" "[http://sequoia.continuent.org/dtds/sequoia-2.10.2.dtd">]
<SEQUOIA>
<VirtualDatabase name="lportal">
<Distribution>
<MessageTimeouts/>
</Distribution>
<Backup>
<Backuper backuperName="Octopus"
className="org.continuent.sequoia.controller.backup.backupers.OctopusBackuper"
options="zip=true"/>
</Backup>
<AuthenticationManager>
<Admin>
<User username="admin" password="adminPassword"/>
</Admin>
<VirtualUsers>
<VirtualLogin vLogin="user" vPassword="userPassord"/>
</VirtualUsers>
</AuthenticationManager>
<DatabaseBackend name="database3" driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:hsql://192.168.10.13:9004" connectionTestStatement="call now()">
<ConnectionManager vLogin="user" rLogin="sa" rPassword="">
<VariablePoolConnectionManager initPoolSize="10" minPoolSize="5" maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
</ConnectionManager>
</DatabaseBackend>
<DatabaseBackend name="database4" driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:hsql://192.168.10.14:9005" connectionTestStatement="call now()">
<ConnectionManager vLogin="user" rLogin="sa" rPassword="">
<VariablePoolConnectionManager initPoolSize="10" minPoolSize="5" maxPoolSize="50" idleTimeout="30" waitTimeout="10"/>
</ConnectionManager>
</DatabaseBackend>
<RequestManager>
<RequestScheduler>
<RAIDb-1Scheduler level="passThrough"/>
</RequestScheduler>
<LoadBalancer>
<RAIDb-1>
<WaitForCompletion policy="first"/>
<RAIDb-1-LeastPendingRequestsFirst/>
</RAIDb-1>
</LoadBalancer>
<RecoveryLog driver="org.hsqldb.jdbcDriver"
url="jdbc:hsqldb:hsql://192.168.10.15:9006" login="sa" password="">
<RecoveryLogTable tableName="RECOVERY" logIdColumnType="BIGINT NOT NULL"
vloginColumnType="VARCHAR NOT NULL" sqlColumnType="VARCHAR NOT NULL"
extraStatementDefinition=",PRIMARY KEY (log_id)"/>
<CheckpointTable tableName="CHECKPOINT"
checkpointNameColumnType="VARCHAR NOT NULL"/>
<BackendTable tableName="BACKEND"
databaseNameColumnType="VARCHAR NOT NULL"
backendNameColumnType="VARCHAR NOT NULL"
checkpointNameColumnType="VARCHAR NOT NULL"/>
<DumpTable tableName="DUMP" dumpNameColumnType="VARCHAR NOT NULL"
dumpDateColumnType="TIMESTAMP"
dumpPathColumnType="VARCHAR NOT NULL"
dumpFormatColumnType="VARCHAR NOT NULL"
checkpointNameColumnType="VARCHAR NOT NULL"
backendNameColumnType="VARCHAR NOT NULL"
tablesColumnType="VARCHAR NOT NULL"/>
</RecoveryLog>
</RequestManager>
</VirtualDatabase>
</SEQUOIA>
Start Controller
Step 1: $SEQUOIA_HOME/bin/controller.sh -f ../config/controller/liferayController1.xml
Step 2: $SEQUOIA_HOME/bin/controller.sh -f ../config/controller/liferayController2.xml
Step 3: Thie step is required to ininitialize virtual databases at the first time only
In Linux: $SEQUOIA_HOME/bin/console.sh
In Windows: %SEQUOIA_HOME%/bin/console.bat
type:
admin lportal
admin
adminPassword
expert on
initialize database1
backup database1 backup1 Octopus .
sa
enable database1
restore backend database2 backup1
sa
enable database2
restore backend database3 backup1
sa
enable database3
restore backend database4 backup1
sa
enable database4
show backend *
quit
quit
Liferay configuration
Step 1: JDBC Driver
copy $SEQUOIA_HOME/drivers/sequoia-driver.jar to $TOMCAT_HOME/common/lib/ext
Step 2: ROOT.xml
Connect Sequoia virtual databases, clustering jdbc is scalarable to cluster one to many database connection:
Virtual database 1: 192.168.10.19
Virtual database 2: 192.168.10.20
Modify file $TOMCAT_HOME/conf/Catalina/localhost/ROOT.xml
<Resource
name="jdbc/LiferayPool"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.continuent.sequoia.driver.Driver"
url="jdbc:sequoia://192.168.10.19:25322,192.168.10.20:25323/lportal"
username="user"
password="userPassword"
maxActive="20"
/>
Step 3: portal-ext.properties
Add below statement to $TOMCAT_HOME/webapps/ROOT/WEB-INF/classes/portal-ext.properties
hibernate.dialect=org.hibernate.dialect.HSQLDialect
Start Tomcat
In Linux, start Liferay at $TOMCAT_HOME/bin/startup.sh
In Windows, %TOMCAT_HOME%/bin/startup.bat
Shutdown procedure
Step 1: Shutdown Liferay:
In Linux, $TOMCAT_HOME/bin/shutdown.sh
In Windows, %TOMCAT_HOME%/bin/shutdown.bat
Step 2: Shutdown Sequoia:
In Linux, $SEQUOIA_HOME/bin/console.sh
In Windows, %SEQUOIA_HOME%/bin/console.bat
type:
shutdown virtualdatabase lportal
shutdown
quit
Reference
http://sequoia.continuent.org/HomePage
http://www.onlamp.com/pub/wlg/7963
Dynamic Virtual Hosting
Liferay provides a new dynamic virtual hosting model starting with version 4.2. New dynamic virtual hosting will let you to add virtual hosts without restarting tomcat. All hosts are served by the same webapps.
Related Articles
Clustering
Using Terracota with Liferay