|
Introduction
Here I wrote up a little tutorial how to configure a standard RHEL cluster. Configuring a RHEL cluster is quite easy but documentation is sparse and not well organized. We will configure a 4 nodes cluster with shared storage and Heatbeat over a different NIC (not the main data link).
Cluster configuration goals
- Shared storage
- HA-LVM: lvm failover configuration (like HP ServiceGuard) is different from clustered logical volume manager (clvm)!!
- Bonded main data link (eg. bond0 –> eth0 + eth1)
- Hearthbeat on a different data link (eg. eth2)
Cluster installation steps
OS installation
First we performed a full CentOS 5.5 installation using kickstart, we also installed cluster packages like:
- cman
- rgmanager
- qdiskd
- ccs_tools
or
- @clustering (kickstart group)
Networking configuration
We configure 2 different data link:
- Main data link (for applications)
- Heartbeat data link (for cluster communication)
Main data link (bond0) uses ethernet bonding over 2 phisycal eth (eth0, eth1). This configuration assures network high availability when some network paths fail.
Cluster communication (heartbeat) uses a dedicated ethernet link (eth2), configured in a diffentent network and vlan.
To obtain such configuration cerate this file /etc/sysconfig/network-scripts/ifcfg-bond0 from scratch and fill it as below:
DEVICE=bond0
IPADDR=<your server main IP address (eg. 10.200.56.41)>
NETMASK=<your server main network mask (eg. 255.255.255.0)>
NETWORK=<your server main network (eg. 10.200.56.0)>
BROADCAST=<your server main network broadcast (eg. 10.200.56.255)>
ONBOOT=yes
BOOTPROTO=none
USERCTL=no
BONDING_OPTS='miimon=100 mode=1'
GATEWAY=<your server main default gateway (eg. 10.200.56.1)>
TYPE=Ethernet
You can customize BONDING_OPT . Please see bonding documentation.
Modify /etc/sysconfig/network-scripts/ifcfg-eth{0,1} :
DEVICE=<eth0 or eth1, etc...>
USECTL=no
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
HWADDR=<your eth MAC address (eg. 00:23:7d:3c:18:40)>
ONBOOT=yes
TYPE=Ethernet
Modify heartbeat nic /etc/sysconfig/network-scripts/ifcfg-eth2 :
DEVICE=eth2
HWADDR=<your eth MAC address (eg. 00:23:7D:3C:CE:96)>
ONBOOT=yes
BOOTPROTO=none
TYPE=Ethernet
NETMASK=<your server heartbeat network mask (eg. 255.255.255.0)>
IPADDR=<your server main IP address (eg. 192.168.133.41)>
Note that heartbeat eth2 has no default gateway configured. Normally this is not required unless this node is outside other node’s network and there are not specific static routes.
Add this line to /etc/modprobe.conf :
alias bond0 bonding
Add to /etc/hosts the informations about each cluster node and replicate the file among the nodes:
# These are example!!!
10.200.56.41 artu.yourdomain.com artu
192.168.133.41 h-artu.yourdomain.com h-artu
10.200.56.42 ginevra.yourdomain.com ginevra
192.168.133.42 h-ginevra.yourdomain.com h-ginevra
10.200.56.43 morgana.yourdomain.com morgana
192.168.133.43 h-morgana.yourdomain.com h-morgana
10.200.56.44 lancelot.yourdomain.com lancelot
192.168.133.44 h-lancelot.yourdomain.com h-lancelot
Logical Volume Manager configuration
We choose not to use clustered logical volume manager (clvmd, sometimes called LVMFailover) but to use HA-LVM instead. HA-LVM is totally different from clvmd and it is quite similar di HP ServiceGuard behaviour.
HA-LVM features
- No needs to run any daemon (like clvmd aka LVMFailover)
- Each volume group can be activated exclusively on one node at a time
- Volume group configuration is not replicated automatically among the nodes (need to run vgscan on the nodes)
- Implementation not dipendent of the cluster status (can work without cluster running at all)
HA-LVM howto
Configure /etc/lvm/lvm.conf as below:
Substitute existing filter with:
filter = [ "a/dev/mpath/.*/", "a/c[0-9]d[0-9]p[0-9]$/", "a/sd*/", "r/.*/" ]
check locking_type :
locking_type = 1
substitute existing volume_list with:
volume_list = [ "vg00", "<quorum disk volume group>", "@<hostname related to heartbeat nic>" ]
Where:
- vg00 is the name of the root volume group (always active)
- <quorum disk volume group> is the name of the quorum disk volume group (always active)
- @<hostname related to heartbeat nic> is a tag. Each volume group can have one tag at a time. Cluster lvm agents tag the volume groups with the hostname (present into configuration) in order to activate them. LVM activate only volume groups that contain such tag. In this way each volume group tagged can be activated and accessed by one node at a time (because of volume_list settings)
At the end remember to regenerate initrd!
# mkinitrd -f /boot/initrd-$(uname -r).img $(uname -r)
Storage configuration
Depending of your storage system, you should configure multipath, and each should be able to access to the same luns.
Quorum disk
Quorum disk is a 20MB LUN shared on the storage to all cluster nodes. This disk is used by the cluster to tie-break in case of split-brain events. Each node update its own information to the quorum disk. If some nodes experience network problems, the quorum disk assures that only the right group of nodes form the cluster but not both (split-brain)!
Quorum disk creation
First be sure that each node can see the same 20MB LUN. Then, on the first node, create a physical volume:
# pvcreate /dev/mpath1
create a dedicated volume group:
# vgcreate -s 8 vg_qdisk /dev/mpath1
create a logical volume and extend it to maximun volume group size:
# lvcreate -l <max_vg_pe> -n lv_qdisk vg_qdisk
Make sure that this volume group is present into volume_list inside /etc/lvm/lvm.conf . It should be activated on all nodes!
On the other nodes perform a:
# vgscan
Should appear the quorum disk volume group.
Quorum disk configuration
Now we have to populate quorum disk space with the right information. To perform this type:
# mkqdisk -c /dev/vg_qdisk/lv_qdisk -l <your_cluster_name>
Note that is not required to use your cluster name as quorum disk label, but it is recommended.
You need also to create a heuristic script to help qdisk when acting as tie-breaker. Create /usr/share/cluster/check_eth_link.sh :
#!/bin/sh
# Network link status checker
ethtool $1 | grep -q "Link detected.*yes"
exit $?
Now activate the quorum disk:
# service qdiskd start
# chkconfig qdiskd on
Logging configuration
In order to assure a good logging you can choose to log the rgmanager to a specific file.
Add this lines to /etc/syslog.conf :
# Red Hat Cluster
local4.* /var/log/rgmanager
Add /var/log/rgmanager to logrotate syslog settings in /etc/logrotate.d/syslog :
/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron /var/log/rgmanager {
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
/bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
Modify this line in /etc/cluster/cluster.conf :
<rm log_facility="local4" log_level="5">
Increment /etc/cluster/cluster.conf version and update on all nodes:
# ccs_tool update /etc/cluster/cluster.conf
Cluster configuration
For configuring cluster you can choose to use:
- Luci web interface
- Manual xml configuration
Configuring cluster using luci
In order to use luci web interface you need to activate service ricci on all nodes and luci on one node only:
(on all nodes)
# chkconfig ricci on
# service ricci start
(choose only a node)
# chkconfig luci on
# luci_admin init
# service luci restart
Please note that luci_admin init must be executed only the first time and before starting luci service, otherwise luci will be unusable.
now connect to luci: https://node_with_luci.mydomain.com:8084 Here you can create a cluster, add nodes, create services, failover domains etc…
See Recommended cluster configuration to learn the right settings for the cluster.
Configuring cluster editing the XML
You can also manually configure a cluster editing its main config file /etc/cluster/cluster.conf . To create the config skeleton use:
# ccs_tool create
now the just created config file is not yet usable, you should configure cluster settings, add nodes, create services, failover domains etc…
When config file is complete, copy the file on all nodes and start the cluster in this way:
(on all nodes)
# chkconfig cman on
# chkconfig rgmanager on
# service cman start
# service rgmanager start
See Recommended cluster configuration to learn the right settings for the cluster.
See Useful cluster commands to learn some useful console cluster commands to use.
Recommended cluster configuration
Here is attached a /etc/cluster/cluster.conf file of a fully configured cluster.
For commenting purposes, the file is splitted into several consecutive parts:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?xml version="1.0"?>
<cluster alias="jcaps_prd" config_version="26" name="jcaps_prd">
<fence_daemon clean_start="0" post_fail_delay="0" post_join_delay="3"/>
<clusternodes>
<clusternode name="h-lancelot.yourdomain.com" nodeid="1" votes="1">
<fence/>
</clusternode>
<clusternode name="h-artu.yourdomain.com" nodeid="2" votes="1">
<fence/>
</clusternode>
<clusternode name="h-morgana.yourdomain.com" nodeid="3" votes="1">
<fence/>
</clusternode>
</clusternodes>
<cman expected_votes="4"/>
<fencedevices/>
|
This is the first part of the XML cluster config file.
- First line describes the cluster name and the
config_version . Each time you modify the XML you must increment the config_version by 1 prior to update the config on all nodes.
- Fence deamon line is the default one.
- Cluster node stanza contains the nodes of the cluster. Note that
name property contains the FQDN of the name. This name determines the eth used for cluster communication. In this example we don’t use the main hostname but the hostname related to the eth we choose to use as cluster communication channel.
- Note also that the line
<fence/> is required. Note that here we do not use any fence device. Due to the nature of HA-LVM the access to the data sould be exclusive by one node at a time.
- Cman
expected_votes is 4 because each node give 1 vote each.
1
2
3
4
5
6
7
8
9
|
<rm log_facility="local4" log_level="5">
<failoverdomains>
<failoverdomain name="jcaps_prd" nofailback="0" ordered="0" restricted="1">
<failoverdomainnode name="h-lancelot.yourdomain.com" priority="1"/>
<failoverdomainnode name="h-artu.yourdomain.com" priority="1"/>
<failoverdomainnode name="h-morgana.yourdomain.com" priority="1"/>
</failoverdomain>
</failoverdomains>
<resources/>
|
This section begins resource manager configuration (<rm ...> ).
- Resource manager section can be configured for logging. Rm logs to syslog, here we configured the
log_facility and the logging level. The facility we specified allows us to log to a separate file (see logging configuration)
- We configured also a failover domain containing all cluster node. We want that a service can switch to all cluster nodes, but you can also configure different behaviours here.
1
2
3
4
5
6
7
8
9
|
<service autostart="1" domain="jcaps_prd" exclusive="0" name="subversion" recovery="relocate">
<ip address="10.200.56.60" monitor_link="1"/>
<lvm name="vg_subversion_apps" vg_name="vg_subversion_apps"/>
<lvm name="vg_subversion_data" vg_name="vg_subversion_data"/>
<fs device="/dev/vg_subversion_apps/lv_apps" force_fsck="1" force_unmount="1" fsid="61039" fstype="ext3" mountpoint="/apps/subversion" name="svn_apps" self_fence="0">
<fs device="/dev/vg_subversion_data/lv_repositories" force_fsck="1" force_unmount="1" fsid="3193" fstype="ext3" mountpoint="/apps/subversion/repositories" name="svn_repositories" self_fence="0"/>
</fs>
<script file="/my_cluster_scripts/subversion/subversion.sh" name="subversion"/>
</service>
|
This section contains the services in the cluster (like HP ServiceGuard packages)
- We choose the failover domain (in this case our failover domain contains all nodes so the service can run on all nodes)
- We add a ip address resource (use always monitor link!)
- We use also a HA-LVM resource (
<lvm ...> ). Here all VG specified will be tagged with the node name when activating. This means that they can be activated only on the node where the service is running (only on that node!). Note: If you do not specify any LV, all the LVs inside the VG will be activated!
- Next there are also
<fs ...> tags for mounting filesystem resources. It is recommended to use force_unmount and force_fsck .
- You can specify also a custom script for starting application/services and so on. Please note that the script must be LSB compliant. This means that it must handle start|stop|status. Note also that default cluster behaviour is to run the script with status parameter every 30 seconds. If the script status does not return 0, the service will be marked as failed (and probably will be restarted/relocated).
This section closes the resource manager configuration (closes XML tag).
1
|
<totem consensus="4800" join="60" token="20000" token_retransmits_before_loss_const="20"/>
|
This is a crucial part of cluster configuration. Here you specify the failure detection time of cluster.
- RedHat recommends to the CMAN membership (token) timeout value to be at least times that of the qdiskd timeout value. Here the value is 20 seconds.
1
2
3
|
<quorumd interval="2" label="jcaps_prd_qdisk" min_score="2" tko="5" votes="1">
<heuristic interval="2" program="/usr/share/cluster/check_eth_link.sh bond0" score="3"/>
</quorumd>
|
Here we configure the quorum disk to be used by the cluster.
- We choose a quorum timeout value of 10 seconds (quorumd interval * quorumd tko) which is a half of token timeout (20 seconds).
- We insert also a heuristic script to determine the network health. This will help qdisk to take a decision when split-brain happens.
This concludes the configuration file closing XML tags still opened.
Useful cluster commands
- ccs_tool update /etc/cluster/cluster.conf (update cluster.conf among all nodes)
- clustat (see cluster status)
- clusvcadm -e <service> (enable/start a service)
- clusvcadm -d <service> (disable/stop service)
- vgs -o vg_name,vg_size,vg_tags (show all volume groups names, size and tags)
Resources
Red Hat web server configuration for Mod_jk
In order to start the EWS for Mod_jk
Step 1: First extract the Zip file go to the folder C:\RHATews-1.0.2-windows32-i386\Red Hat\Enterprise Web Server\etc\httpd\conf
Step 2 : Rename the File httpd.conf.in to httpd.conf
Step 3 : Change the Default Listen Listen 127.0.0.1:80 to Listen *:80
Step 4 : Change the following to their Corresponding LIB Folder
Ex : LoadModule auth_basic_module ../../lib/httpd/modules/mod_auth_basic.so
Step 4 : Include the following for the MOD_JK Configuration,
# Include mod_jk’s specific configuration file
Include conf/mod_jk.conf
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
Step 5 : Now Rename the file mod_jk.conf.sample to mod_jk
Step 6 : Replace the following LoadModule jk_module modules/mod_jk.so to
LoadModule jk_module ../../lib/httpd/modules/mod_jk.so
Step 7 : Provide your application name
# Mount your applications
JkMount /application/* loadbalancer
Step 8 : Comment the Deny location
Step 9 : Rename the uriworkermap.properties.sample to uriworkermap
Step 10 : Remove all and just add the below,
# Simple worker configuration file
# Mount the Servlet context to the ajp13 worker
/jmx-console=loadbalancer
/jmx-console/*=loadbalancer
/web-console=loadbalancer
/web-console/*=loadbalancer
/ghie/*=loadbalancer
Step 11 :Rename the workers.properties.jboss.sample to workers
Define the JBOSS EAP SERVER BOX IP and its Port No in the following
Provide the Node Details
# Define Node1
# modify the host as your host IP or DNS name.
worker.node1.port=8009
worker.node1.host=192.168.7.99
worker.node1.type=ajp13
worker.node1.ping_mode=A
worker.node1.lbfactor=1
# Define Node2
# modify the host as your host IP or DNS name.
worker.node2.port=8009
worker.node2.host=192.168.7.60
worker.node2.type=ajp13
worker.node2.ping_mode=B
worker.node2.lbfactor=2
#worker.node2.cachesize=10
Step 12 :Enable the Sticky session by adding the following bold line
# Load-balancing behavior
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=1
Step 13 : Move to the Folder C:\RHATews-1.0.2-windows32-i386\Red Hat\Enterprise Web Server\etc\httpd\conf.d
Step 14 :Rename the Following File manual.conf.in to manual
Step 15 :Rename the following file proxy_ajp.conf.in to proxy_ajp
Change the following ,
LoadModule proxy_ajp_module ../../lib/httpd/modules//mod_proxy_ajp.so
Step 16 :Rename the file ssl.conf.in to ssl
Change the following,
LoadModule ssl_module ../../lib/httpd/modules//mod_ssl.so
Listen localhost:443 to Listen 443
Step 17 :Uncomment the following line and add the Server Name and Server Admin
DocumentRoot “/Program Files/Red Hat/Enterprise Web Server/var/www/html”
ServerName localhost:443
ServerAdmin rmohan@rmohan.com
Step 18 : Add the following ,
JkMountCopy On
JkMount /ghie/* loadbalancer
Step 19 :Rename the file welcome.conf.in to welcome.
Step 20 :Add a Folder logs,run in the following path C:\RHATews-1.0.2-windows32-i386\Red Hat\Enterprise Web Server\etc\httpd
Step 21 :Rename the File mime.types.in to mime.types in the path C:\RHATews-1.0.2-windows32-i386\Red Hat\Enterprise Web Server\etc
Step 22:Rename the File charset.conv.in to charset.conv in the path C:\RHATews-1.0.2-windows32-i386\Red Hat\Enterprise Web Server\etc
Step 23 :In the following path add your Index HTML Page so that it will be displayed for you while running the EWS,
C:\RHATews-1.0.2-windows32-i386\Red Hat\Enterprise Web Server\var\www\html
Step 24 :To Start the Server go to the folder C:\RHATews-1.0.2-windows32-i386\Red Hat\Enterprise Web Server\bin
Run using the httpd.exe
Configuration of Jboss EAP Server 6.0
To do clustering we need two different box with Jboss EAP Server 6.0
NOTE :Make the following changes in BOX 1 which is Node 1 in MOD_JK
Step 25 :Copy the folder Standalone and save it in the same path and rename it as standalone-node1
C:\EAP-6.0.0.GA\jboss-eap-6.0\standalone
Step 26 :Add the Following in Standalone.xml file
Note :In the certificate –file provide your keystore file that you have created for ssl
Step27 :In the standalone-ha.xml add the following,
Provide the Name for the server
Step 28 :Change the default-stack from udp to tcp
Step 29 :Include the following under
node1 ip(192.168.7.99[7600]),node2 ip(192.168.7.60[7600])
2
0
2000
Step 30 :Add the following instance-id ,connector ajp and https line under the subsystem urn:jboss:domain:web:1.1
<subsystem xmlns=”urn:jboss:domain:web:1.1″ default-virtual-server=”default-host” instance-id=”${jboss.node.name}” native=”false”>
Step 31 :Deploy your project under deployement folder.
Step 32 :To Start the Jboss EAP Server 6.0 in cluster mode use the following command,
C:\EAP-6.0.0.GA\jboss-eap-6.0\bin>standalone.bat -c standalone-ha.xml –b Hostname( 192.168.7.60) -Djboss.server.base.dir=../standalone-node1 -Djboss.node.name=node1
Ex:
standalone.bat -c standalone-ha.xml –b 192.168.7.60 -Djboss.server.base.dir=../standalone-node1 -Djboss.node.name=node1
standalone.bat -c standalone-ha.xml –b 192.168.7.99 -Djboss.server.base.dir=../standalone-node2 -Djboss.node.name=node2
Do the same for the Jboss EAP Server 2 and replace Standalone-node1 to standalone-node2.
Tomcat memory overflow reasons
Bad tomcat memory settings in a production environment is prone to memory overflow. Cause memory overflow is not the same, of course, not the same approach. Here is a summary of the usually encountered and related information. The common general there will be the following three conditions: 1.OutOfMemoryError: Java heap space 2.OutOfMemoryError: PermGen space 3.OutOfMemoryError: unable to create new native thread. Tomcat memory overflow solution For the first two cases, the application itself is not a memory leak tomcat jvm parameters settings to solve. (-Xms-Xmx-XX: PermSize-XX: MaxPermSize) Finally, one may need to adjust the operating system and the tomcat jvm parameters adjusted simultaneously in order to achieve their goals. The first: a heap overflow. Analysis: JVM heap setting is the java program is running in the JVM memory space deployment settings. JVM startup automatically set Heap size value, the initial space (ie-Xms) is the physical memory of 1/64 maximum space (-Xmx) is 1/4 of the physical memory. JVM can be used to provide the-Xmn-Xms-Xmx and other options can be set. The Heap size size is the Young Generation and the Tenured Generaion and. If 98% of the time for the JVM GC and Heap size available for less than 2% of the time will throw this exception. Heap Size should not exceed 80% of the available physical memory, the To-Xms and-Xmx option set to the same-Xmn 1/4-Xmx value. Memory leak case, adjust-Xms-Xmx parameter can be resolved. -Xms: Initial heap size -Xmx: maximum heap size But the impact of the size of the heap by the following three aspects: A data model of the operating system (32-bt or 64-bit) limit; (32-bit systems, the general restrictions in 1.5G and 2G; 2003 server system (physical memory: 4G and 6G, jdk: 1.6 ) test 1612M, 64-bit operating system, unlimited memory.) System available virtual memory limit; 3. System available physical memory limit. Heap size of java-Xmx *** M version command can be used to test. Support jdk version number will appear, does not support error. Better-Xms-Xmx generally configured as such set JAVA_OPTS =-Xms1024m-Xmx1024m Its initial space (ie-Xms) is the physical memory of 1/64, the largest space (-Xmx) is 1/4 of the physical memory. JVM can be used to provide the-Xmn-Xms-Xmx options Set Instance, the reference given below 1G memory environment java jvm parameter settings: JAVA_OPTS = “-server-Xms800m-Xmx800m-XX: PermSize = 64M-XX: MaxNewSize = 256m-XX: MaxPermSize = 128m-Djava.awt.headless = true” JAVA_OPTS = “-server-Xms768m-Xmx768m-XX: PermSize = 128m-XX: MaxPermSize = 256m-XX: NewSize = 192m-XX: MaxNewSize = 384m “ CATALINA_OPTS = “-server-Xms768m-Xmx768m-XX: PermSize = 128m-XX: MaxPermSize = 256m -XX: NewSize = 192m-XX: MaxNewSize = 384m “ Server 1G memory: JAVA_OPTS = “-server-Xms800m-Xmx800m-XX: PermSize = 64M-XX: MaxNewSize = 256m-XX: MaxPermSize = 128m-Djava.awt.headless = true” Server 64, the 2G memory: JAVA_OPTS = ‘-server-Xms1024m-Xmx1536m-XX: PermSize = 128M-XX: MaxNewSize = 256m-XX: MaxPermSize = 256m’ ——————- Solution 1: ————————— – Premise: perform startup.bat start tomcat Linux server: Catalina.sh under the the / usr/local/apache-tomcat-5.5.23/bin directory Add: JAVA_OPTS = ‘-Xms512m-Xmx1024m’ Or JAVA_OPTS = “-server-Xms800m-Xmx800m-XX: MaxNewSize = 256m” Or the CATALINA_OPTS = “-server-Xms256m-Xmx300m” Windows Server: Join in catalina.bat the front set JAVA_OPTS =-Xms128m-Xmx350m Or set CATALINA_OPTS =-Xmx300M-Xms256M (The difference is a direct set jvm memory, another set tomcat memory and JAVA_OPTS, CATALINA_OPTS seems to be the indiscriminate use) Basic Parameter Description -Client,-server These two parameters are used to set up virtual machines which run mode must be used as the first parameter, client mode is enabled faster runtime performance and memory management less efficient than server mode, usually for the client application. Instead, server mode starts slower than the client, but the availability of higher operating performance. On the windows, type the default virtual machine client mode, if you want to use the server mode, you need to start a virtual machine add-server parameters in order to obtain a more high-performance, server-side applications, server mode is recommended, especially Multiple CPU system. Linux, Solaris server mode by default. In addition, in the multi-cup, proposed to use the server mode -Xms <size> Set up a virtual machine available memory of the initial size of the heap, the default unit of bytes, the size of an integer multiple of 1024 and greater than 1MB, k (K) or m (M) is a unit available to set up a large number of memory . The initial heap size is 2MB. Plus “m” MB, or is KB. For example:-Xms6400K,-Xms256M -Xmx <size> Set the maximum available size of the virtual machine, the default unit is bytes. The value must be 1024 integer multiple of, and greater than 2MB. Available k (K) or m (M) to set up a large number of memory units. The default heap maximum of 64MB. For example:-Xmx81920K,-Xmx80M When the application for large memory to run virtual machine throws a java.lang.OutOfMemoryError: Java heap space error, you need to use the-Xmx settings available memory heap. PermSize / MaxPermSize: definition of Perm segment size, ie permanent preservation of the size of the area, PermSize JVM startup memory size initialization Perm; MaxPermSize maximum memory size occupied Perm. These two values are set to the same general user production environment, in order to reduce the overhead spent during the operation of the system in the memory application. If startup.bat start tomcat, OK settings to take effect. Successful enough allocated 200M memory. ——————- Solution 2: ———————— Premise: perform startup.bat start tomcat Manually set the Heap size Windows Server: Modify the TOMCAT_HOME / bin / catalina.bat, in the “echo” Using CATALINA_BASE: $ CATALINA_BASE “” above, add the following line: Java code set JAVA_OPTS =% JAVA_OPTS%-server-Xms800m-Xmx800m-XX: MaxNewSize = 256m Note: JAVA_OPTS retain the previous settings. Linux server: Modify the TOMCAT_HOME / bin / catalina.sh In “echo” Using CATALINA_BASE: $ CATALINA_BASE “” above, add the following line: JAVA_OPTS = “$ JAVA_OPTS-server-Xms800m-Xmx800m-XX: MaxNewSize = 256m” Note: $ JAVA_OPTS retain the previous settings. ——————- Solution 3: ————————— – Premise: system services for the implementation of the windows start tomcat But if not execute startup.bat start tomcat but to use the windows system services start tomcat service, the above settings will not take effect, That set JAVA_OPTS =-Xms128m-Xmx350m did not work. The above allocation 200M memory on OOM .. The windows services performed the bin \ tomcat.exe. reads registry value, and not catalina.bat settings. The solution: Modify the registry HKEY_LOCAL_MACHINE \ SOFTWARE \ Apache Software Foundation \ Tomcat Service Manager \ Tomcat5 \ Parameters \ JavaOptions Cost for -Dcatalina.home = “C: \ ApacheGroup \ Tomcat 5.0” -Djava.endorsed.dirs = “C: \ ApacheGroup \ Tomcat 5.0 \ common \ endorsed” -Xrs Join-Xms300m-Xmx350m Restart the tomcat service, set to take effect ——————- Solution 4: ————————— – Premise: system services for the implementation of the windows start tomcat Install tomcat if so check the “NT Service (NT/2000/XP only)” After the installation is complete there will be a “bin” directory in the installation directory tomcat.exe file Tomcat’s first service will be turned off In the command line mode (Run, enter CMD) Change directory to the bin directory of tomcat Use the following command to remove the service tomcat-uninstall “Apache Tomcat 4.1” Next, write a batch. Reads as follows set SERVICENAME = Apache Tomcat 4.1 set CATALINA_HOME = E: \ Tomcat 4.1.24 set CLASSPATH = D: \ j2sdk1.4.1_01 \ lib set JAVACLASSPATH =% CLASSPATH% set JAVACLASSPATH =% JAVACLASSPATH%;% CATALINA_HOME% \ bin \ bootstrap.jar set JAVACLASSPATH =% JAVACLASSPATH%;% CATALINA_HOME% \ common \ lib \ servlet.jar set JAVACLASSPATH =% JAVACLASSPATH%;% JAVA_HOME% \ lib \ tools.jar tomcat.exe-install “% SERVICENAME%” “% JAVA_HOME% \ jre \ bin \ server \ jvm.dll”-Djava.class.path = “% JAVACLASSPATH%”-Dcatalina.home = “% CATALINA_HOME%”-Xms512m – Xmx768m-start org.apache.catalina.startup.Bootstrap-params start-stop org.apache.catalina.startup.Bootstrap-params stop-out “% CATALINA_HOME% \ logs \ stdout.log”-err “% CATALINA_HOME% \ logs \ stderr.log “ Note that the last line from tomcat.exe-install! Do not carriage return line feed this line is divided into several paragraphs. Saved in the command line, run this bat file, when you pay attention to the implementation of the “service” window is closed. The second: permanent preservation area overflow Analysis: PermGen space stands for Permanent Generation space, refers to the permanent preservation area of memory, this memory the JVM storage Class and Meta information, Class Loader, will be on the PermGen space, and store instances of the class (Instance) Heap area, GC (Garbage Collection) is not in the main program running to clean up the PermGen space, so if your application very CLASS, it is likely PermGen space error, this error is common in web server JSP to pre compile time. If you WEB APP with a large number of third-party jar size than the the jvm default size (4M) it will produce this error message. Hibernate and spring projects are also very prone to this problem. Might these frameworks dynamically class and jvm the gc will not clean PemGen space over jvm default size (4M) cause a memory overflow. Recommendation: the same third-party jar files relocated to the tomcat / shared / lib directory, so you can achieve the purpose of reducing jar document repeated memory. This is a general increase-XX: PermSize-XX: MaxPermSize to solve the problem. -XX: PermSize initial size of the permanent preservation areas -XX: PermSize initial maximum permanent preservation areas This is generally combined with the first use, such as set JAVA_OPTS =-Xms1024m-Xmx1024m-XX: PermSize = 128M-XX: PermSize = 256M One thing to note: the maximum heap memory java-Xmx *** M version command to test-Xmx and-XX: PermSize and such as system support jvm heap size things 1.5G, that-Xmx1024m-XX: PermSize = 768M is unable to run. —————– Solution 1: ————————- Linux server: Increase in the the catalina.sh first line: JAVA_OPTS = -Xms64m -Xmx256m -XX: PermSize = 128M -XX: MaxNewSize = 256m -XX: MaxPermSize = 256m Or In “echo” Using CATALINA_BASE: $ CATALINA_BASE “” above, add the following line: JAVA_OPTS = “-server-XX: PermSize = 64M-XX: MaxPermSize = 128m Windows Server: Increase in the first row of the catalina.bat: set JAVA_OPTS =-Xms64m-Xmx256m-XX: PermSize = 128M-XX: MaxNewSize = 256m-XX: MaxPermSize = 256m —————– Solution 2: ———————— Modify TOMCAT_HOME / bin / catalina.bat (Linux catalina.sh) code in Java “Echo” Using CATALINA_BASE: $ CATALINA_BASE “” above, add the following line: set JAVA_OPTS =% JAVA_OPTS%-server-XX: PermSize = 128M-XX: MaxPermSize = 512m “Echo” Using CATALINA_BASE: $ CATALINA_BASE “” above, add the following line: set JAVA_OPTS =% JAVA_OPTS%-server-XX: PermSize = 128M-XX: MaxPermSize = 512m The catalina.sh next: Java code JAVA_OPTS = “$ JAVA_OPTS-server-XX: PermSize = 128M-XX: MaxPermSize = 512m” JAVA_OPTS = “$ JAVA_OPTS-server-XX: PermSize = 128M-XX: MaxPermSize = 512m” Third: Can not create a new thread. This phenomenon is relatively rare, strange proportion and the jvm with system memory. Such strange because the JVM has been assigned by the system a lot of memory (such as 1.5G), and it takes up at least half of the available memory. It was found that, in many cases the number of threads allocated to the JVM memory more, then the likelihood of the above error is greater. Cause Analysis (Learned from this blog reason: http://hi.baidu.com/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html): A 32-bit process can use up to 2G of memory available, because another 2G retained operating system. It is assumed that the 1.5G to the JVM, then the remaining 500M available memory. Part of the 500M memory must be used for the loading of the system dll, then really the rest perhaps only 400M, key places now appeared: When you use Java to create a thread, will create a Thread object in the JVM memory but also in the operating system at the same time to create a real physical thread (reference JVM specification), the operating system will create the physical thread in the remaining 400 MB of RAM, rather than created in the memory heap of the JVM 1500M. Jdk1.4 inside, the default stack size is 256KB, but in jdk1.5 inside the default stack size for 1M per thread, therefore, in the remaining 400M of memory available inside most we can only create 400 threads available. This conclusion came out, in order to create more threads, you must reduce the maximum memory allocated to the JVM. Another approach is to let the the JVM host in your JNI code inside. Give an estimation formula for the maximum number to be able to create threads: (MaxProcessMemory – JVMMemory – ReservedOsMemory) / (ThreadStackSize) = Number of threads For jdk1.5 terms, assuming that the operating system retain 120M memory: 1.5GB JVM: (2GB-1.5Gb-120MB) / (1MB) = ~ 380 threads 1.0GB JVM: (2GB-1.0Gb-120MB) / (1MB) = ~ 880 threads Have a 2000/XP/2003 inside the boot.ini startup options like :/ PAE / 3G allows users to process maximum memory expansion to 3G when the operating system can only occupy up to 1G of virtual memory. Should be able to let the JVM as create more threads. Therefore, this case requires a combination of operating system-related adjustment. So: we need to combine different tomcat memory allocation different diagnosis in order to fundamentally solve the problem. Detection current JVM memory usage: System.out.println (“JVM MAX MEMORY:” + Runtime.getRuntime (). MaxMemory () / 1024/1024 + “M”); System.out.println (“JVM IS USING MEMORY:” + Runtime.getRuntime (). TotalMemory () / 1024/1024 + “M”); System.out.println (“JVM IS FREE MEMORY:” + Runtime.getRuntime (). FreeMemory () / 1024/1024 + “M”); These three methods are said JVM memory usage rather than the operating system’s memory; maxMemory () method returns the java virtual machine (the process) can structure dug up from the operating system’s memory, in bytes, when running java program, no add-Xmx parameter is 64 trillion, that is maxMemory () returned about 64 * 1024 * 1024 bytes, which is the default java virtual machine the dug memory from the operating system. If you add the-Xmx parameter, will be behind the value of this parameter shall prevail, such as java-cp ClassPath-Xmx512m ClassName, the maximum memory is 512 * 1024 * 0124 bytes. totalMemory () method returns the java virtual machine has now been dug up from the operating system, memory size, this process is the java virtual machine was occupied all memory. -Xms parameters when running java add java program running process, memory is always slowly dug from the operating system, basically how much digging how much straight dug maxMemory () so far So the totalMemory () is slowly increasing. If you use the-Xms parameter, the program in the startup will be unconditional from the operating system, the number of dig the-Xms back defined memory, and memory used about the same time, and then dig. freeMemory () What is it, just talked about-Xms parameters when running java add java program running process, memory is always slowly dug from the operating system, is basically how much dig how much, but the java virtual machine will be 100% of the cases a little more digging point, they dug up but no access memory, is actually freeMemory (), so the value is generally the case freeMemory () are very small, but if you run java program using the-Xms, this time because of the program in the start time will be unconditional dug from the operating system, number of memory-Xms defined later, this time, dig around memory may on most of the useless, so this time freeMemory () may be some ——————– Solution ————————– JVM heap size adjustment Sun HotSpot 1.4.1 generational collector, the heap is divided into three main domains: a new domain, the old domain, as well as permanent domain. Jvm generated by all the new object in the new domain. Once an object has experienced a certain number of garbage collection cycle, the use of the old domain. Class and method objects are stored in a permanent domain jvm. On the configuration, the permanent domain is an independent domain and is not considered to be part of the heap. Here’s how to control the size of these domains. Use-Xms and-Xmx control the entire original size or maximum heap. The following command is to set the initial size to 128M: java-Xms128m The-Xmx256m control the size of the new domain, you can use the-XX: NewRatio set up a new domain in the heap proportion. The following command to set the whole heap 128m, a new domain ratio is set to 3, that the new domain with the old domain ratio of 1:3, a new domain for 1/4 or heap 32M: java-Xms128m-Xmx128m -XX: NewRatio = 3-XX: NewSize and-XX: MaxNewsize set the initial value and the maximum value of the new domains. The following command to set the initial value of the new domain and maximum 64m: java-Xms256m-Xmx256m-Xmn64m The permanent domain default size of 4m. When the program is run, jvm will adjust the size of the permanent domain in order to meet their needs. Each adjustment, jvm be heap the once completely garbage collection. Use the-XX: MaxPerSize flag to take the size increase permanent domain. WebLogic Server application load more often need to increase the maximum value of the permanent domain. When the jvm loaded class time, permanent domain object sharply increased, enabling the jvm continuous adjustment permanent domain size. In order to avoid the adjustment, use the-XX: PerSize flag to set the initial value. Permanent domain below the initial value is set to 32m, and the maximum value is set to 64m. java-Xms512m-Xmx512m-Xmn128m-XX: PermSize = 32m-XX: MaxPermSize = 64m Default, HotSpot copying collector used in the new domain. The domain is generally divided into three parts. The first part of Eden, is used to generate a new object. The other two parts are called drop-in space, when Eden is full, the collector to stop the application, all reachable objects are copied to the current from rescue space, once the current from rescue space is full, the collector put reachable object replication to the current ‘s to rescue space. From and to rescue space swap roles. Objects remain active in rescue space copy, until they get to use, and transferred to the old domain. Use the-XX: SurvivorRatio can control the size of the new domain subspace. With NewRation like the, SurvivorRation provisions in a rescue domain Eden space ratio. For example, the following command set to the new domain 64m Eden accounted for 32m, each rescue domain each 16m: java-Xms256m-Xmx256m-Xmn64m-XX: SurvivorRation = 2 As mentioned earlier, by default HotSpot use the new domain copying collector, use the mark on the old domain – Clear – compressed collector. Copying collector in the new domain to use a lot of sense, because the application generates most of the objects are short-lived. Under ideal conditions, all the transition when the objects in and out of the Eden space will be collected. If this is the case, and the object out of the Eden space is a long-life, then theoretically you can immediately they moved into the old domain, to avoid repeated replication in space rescue. However, the application is not suitable for this ideal state, because they have a small part of the long-lived object. It is best to keep these long-lived object and placed in a new domain, because the object than compressed copy a small part of the old domain cheap. To control the replication of new objects in the domain, the available-XX: TargetSurvivorRatio control the relief space ratio (this value is used in a proportion of the set relief space. Such relief sterically 1M, 50 represents the value of the available 500K). The value is a percentage, the default value is 50. When the the larger stack lower sruvivorratio should increase this value to 80-90, in order to make better use of space rescue. With the-XX: maxtenuring threshold upper control limit. Copy all placed all hope of objects from eden extension to the old domain to the MaxTenuring Threshold can be set to 0. After setting, in fact, no longer use the relief space, and should therefore be SurvivorRatio set to maximum in order to maximize the Eden space, are set as follows: java …-XX: MaxTenuringThreshold = 0-XX: SurvivorRatio = 50000 … Garbage collection: Multi-level garbage collection points, 0 for All (Full) garbage collection, recycling the OLD segment in the garbage; 1 or more for some of the garbage collection, only recycling Young garbage memory overflow usually occurs in the OLD segment or Perm segment after the garbage collection is still free memory space to accommodate the new Java objects. When a URL is accessed, the the memory application process is as follows: A. JVM will attempt to initialize a memory area for the relevant Java objects in Eden B. when Eden space enough, the closing of the application memory. Otherwise, to the next step C. JVM trying to release all inactive objects in Eden (which belong to one or more advanced garbage collection); after the release of the Eden space is still not enough to put a new object, trying to be an active part of the Eden object into the Survivor District / OLD area D. Survivor zone is used to as Eden and OLD intermediate exchange region, Survivor zone object will be moved to the Old OLD area space enough, otherwise it will be retained in Survivor District E. OLD area is not enough space, JVM in OLD area full of garbage collection (0) F. totally garbage collection, Survivor and OLD District still unable to store part of the object copied from Eden, the JVM is not in the Eden District for the new object to create a memory region, “out of memory error” Java heap parameters: ms / mx: defined YOUNG + OLD segment size, ms JVM startup YOUNG + OLD memory size; mx occupied YOUNG + OLD memory size. These two values are set to the same general user production environment, in order to reduce the overhead spent during the operation of the system in the memory application. NewSize / MaxNewSize: size of defined YOUNG segment, YOUNG NewSize JVM startup memory size a; MaxNewSize of occupied YOUNG memory size. These two values are set to the same general user production environment, in order to reduce the overhead spent during the operation of the system in the memory application. PermSize / MaxPermSize: defined Perm segment size, PermSize the JVM startup Perm memory size; MaxPermSize maximum memory size occupied Perm. These two values are set to the same general user production environment, in order to reduce the overhead spent during the operation of the system in the memory application. SurvivorRatio: set the proportion of the Survivor space and the Eden space Example: MEM_ARGS = “-Xms512m-Xmx512m-XX: NewSize = 256m-XX: MaxNewSize = 256m-XX: PermSize = 128m-XX: MaxPermSize = 128m-XX: SurvivorRatio = 6” In the above example: YOUNG + OLD: 512M YOUNG: 256M Perm: 128M Eden: YOUNG * 6 / (6 +1 +1) = 192M Survivor: YOUNG / (6 +1 +1) = 32M The total size of the Java heap = YOUNG + OLD + Perm = 640M
Two weeks ago, I tested a Barracuda Load Balancer Model 340.
I liked it a lot, all features I needed, quick and easy deployment and administration. No competition for a Citrix VPX 1000 or similar, but it would for sure fulfill all my requirements.
Nevertheless I wanted see if it is possible to save some money and built the same functionalities with Apache. My test setup was the following.
1 1x CentOS 6.2 VM with Apache 2 2x Win 2k8 R2 VMs running a Tomcat web server 3 1x Win 2k8 R2 VM running the MSSQL DBMS backend
My challenge: The Linux box should act as a LoadBalancer in front of the two Tomcat servers. SSL offloading on the Apache can be added later on, mod_security and mod_rewrite can be added as well. And in order to make it bulletproof, keepalived could help making this setup HA.
Here is my very basic config:
Apache 2.2 configuration: # create a virtual host and a Proxy balancer #/etc/httpd/conf.d/vhosts.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
<Proxy balancer://cluster1>
BalancerMember ajp://web1.westwind.cx:8009
BalancerMember ajp://web2.westwind.cx:8009
ProxySet lbmethod=bytraffic
</Proxy>
<VirtualHost *:80>
ServerName www.westwind.cx
ProxyPass / balancer://cluster1/
ProxyPassReverse / balancer://cluster1/
</VirtualHost>
Tomcat configuration: #create an AJP connector in the conf/server.xml <!– A AJP 1.3 Connector on port 8009 –> <Connector port=”8009″ address=”${jboss.bind.address}”enableLookups=”false” redirectPort=”8443″ debug=”0″protocol=”AJP/1.3″/>
Scenario-: 1. Configure squid Server 2. Configure Dan guardian 3. Configure Iptables 4. Configure Proxy server as a router. Our purpose of proxy server is to sharing internet connection for web browsing performance & configures Dan guardian for content and site blocking. A. Allow Internal to all user with restricted web site and content. B. Allow limited user can access all site C. Publish local server as a web server in different-different port. D. All user can send receive mail from the Outlook but they can’t access restricted site. E. Allow vnc, Sql server and Remote Desktop Connection access form to internet to External Network. F. Allow company’s website access to all users
Process-: External LAN Card- eth0 (10.10.10.1) Internal LAN Card- eth1(192.168.10.1) 1. Configure and install Squid Server-: # yum install squid* Cp /etc/squid/squid.conf /etc/squid/squid.conf.bkp Vim /etc/squid/squid.conf visible hostname vsnl.com http_port 3128 # Restrict Web access by IP address Acl special_client src “/etc/squid/special_client_ip_txt” # allow all site access users ‘s ip list Acl our_networks src 192.168.10.0/24 # allow network Acl bed url_regex “ /etc/squid/squid/squid-block.acl” # list of block site ‘s name http_access allow bed special_client # allow access all site to special client list http_access deny bed our_networks # allow limited access http_access allow our_networks # allow access to network vim /etc/squid/special_client_ip_txt 192.168.10.126 192.168.10.200 192.168.10.251 vim /etc/squid/squid_block_acl orkut.com yahoo.com gmial.com Service squid start # Service squid stop # Service squid restart Install and Configure Dansguardain -: Yum install dans* Cp /etc/dansguardain/dansguardian.conf /etc/dansguardain/dansguardian.conf.bkp Vim /etc/dansguardian/dansguardain.conf Filter ip = 192.168.10.1 Filter port = 8080 Proxy ip = 127.0.0.1 Proxy port = 3128 Vim /etc/dansguardian/list/bandsitelist Gmail.com # list of block site Yahoo.com Facebook.com Orkut.com Vim /etc/dansguardain/list/bannedregexpurllist # Hard core phase ( for content blocking) Orkut|youtube|sport|gmail|facebook|orkut|sex|video|virus|audio Vim /etc/dansguardian/lists/exceptionsitelist # following site will not be filter by dansguardain. Allow for all users. www.online-linux.blogspot.com www.xyz.com vim/etc/dansguardian/exceptioniplist # list of ip allow all fitler site. 192.168.10.126 192.168.10.200 192.168.10.251 Configure Iptables-: # masquerade local lan(eth1) # redirect all request 80 to 8080 from eth1(local lan) # publish local website # allow 80 and 8080 port $ iptables –t nat –A POSTROUTING –I eth1 –j MASQUERADE $ iptables -t nat -A PREROUTING -i eth1 -p tcp –dport 80 -j REDIRECT –to-port 8080 $ iptables -t nat -A PREROUTING -i eth1 -p tcp –dport 3128 -j REDIRECT –to-port 8080 $ iptables -t nat -A PREROUTING -p tcp -d 10.10.10.1 –dport 8090 -j DNAT –to-destination 192.168.10.10:8090 $ iptables –I INPUT –s 192.168.10.0/24 –p tcp –-dport 80 –J ACCEPT $ iptables –I INPUT –s 192.168.10.0/24 –p tcp –dport 8080 –J ACCEPT
Client Site- Lan setting- 192.168.100.1:8080
Load Balancing -: Load balancer accept request from external client and forward them to one of the available Backend servers according to a scheduling algorithm. We can use dedicated hardware and any load balancing software for load balancing Mod_proxy_balancer- : Apache web server’s module of mod_proxy_balancer the apache module developed to provide to load balancing over a set of web server. Load balancer it can keep track of session Sticky Session- A single user always deals with the same backend server.
 Installation -: Apache modules- Download from apache’s web site, mod_proxy module for load balancing Windows-: Download mod_proxy modules and copy in modules directory. Linux- Download mod_proxy modules and run following command for compile. #./configure –enable-proxy –enable-proxy-balancer [run ./configure –h # make # make install Configuration-: Windows-: Enable following load modules in and add require modules in httpd.conf file C:\Program Files\Apache Software Foundation\Apache2.2\conf\httpd.conf LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so Now we can add following lines for proxy-balancer (Cluster name is domain.abc.net with two member) ProxyRequests Off ProxyPass / balancer://domain.abc.net/ lbmethod=byrequests stickysession=jsessionid nofailover=On maxattempts=15 ProxyPreserveHost OnBalancerMember http://192.168.10.10:84 BalancerMember http://192.168.100.10:85 Linux- We need three servers one is load balancer and other two workers nodes Http Server configuration file “/etc/httpd/conf/httpd.conf” add following lines Include conf/extra/httpd-proxy-balancer.conf Now create the httpd-proxy-balancer.conf file in the “/etc/httpd/conf/httpd.conf” and add the following lines. ProxyRequests Off ProxyPass / balancer://domain.abc.net/ lbmethod=byrequests stickysession=jsessionid nofailover=On maxattempts=15 ProxyPreserveHost OnBalancerMember http://192.168.10.10:84 BalancerMember http://192.168.100.10:85 Load balancing method-: There are three type of load balancing method used in mod_prxy Byrequests-:Weighted request count balancing Bytraffic-: Weighted traffic byte count balancing Bybusyiness-: Pending request balancing Where method is one of the three listed before. Default is byrequestsBalancerMember http://192.168.10.10:84 loadfactor=4 BalancerMember http://192.168.100.10:85 loadfactor=6 A load factor will be applied member of the cluster, in order to define and sharing load balancing between members of cluster. In the following example 40% of the requests will be forwarded to the first and reaming 60% will be forward to second cluster.
ProxyPass / balancer://domain.abc.net/ lbmethod=byrequests stickysession=jsessionid SESSION_ID is the name of the variable at the application level storing the session identifier.
Methods to deal with split-brain situation: 1. Redundant heartbeat path network port communication plus serial port communication 2. I/O fencing Remaining nodes separate failed node from its storage either by shutdown/reboot power port or storage port 3. Quorum disk Quorum disk is a kind of I/O fencing, but the reboot action is executed by failed node’s own quorum daemon. It also has additional feature: contributing vote to cluster. if you want the last standing node to keep the multiple-nodes cluster running, quorum disk appears to be the only solution. RHCS (Red Hat Cluster Suite) Quorum disk facts – A shared block device (SCSI/iSCSI/FC..), Device size requirement is approximately 10MiB – Supports maximum 16 nodes, nodes id must be sequentially ordered – Quorum disk can contribute votes. In multiple nodes cluster, together with quorum vote, the last standing node can still keep the cluster running – single node votes+1 <=Quorum’s disk vote < nodes total votes – The failure of the shared quorum disk won’t result in cluster failure, as long as Quorum’s disk vote < nodes total votes – each node write its own health information in its own region, the health is determined by external checking program such as “ping” Setup Quorum disk
#initialise quorum disk once in any node
mkqdisk -c /dev/sdx -l myqdisk
Add quorum disk to cluster Use luci or system-config-cluster to add quorum disk, following is the result xml file
<clusternodes>
<clusternode name="station1.example.com" nodeid="1" votes="2">
<fence/>
</clusternode>
<clusternode name="station2.example.com" nodeid="2" votes="2">
<fence/>
</clusternode>
<clusternode name="station3.example.com" nodeid="3" votes="2">
<fence/>
</clusternode>
</clusternodes>
#expected votes =9=(nodes total votes + quorum disk votes) = (2+2+2+3)
<cman expected_votes="9"/>
#Health check result is writen to quorum disk every 2 secs
#if health check fails over 5 tko, 10 (2*5) secs, the node is rebooted by quorum daemon
#Each heuristic check is run very 2 secs and earn 1 score,if shell script return is 0
<quorumd interval="2" label="myqdisk" min_score="2" tko="5" votes="3">
<heuristic interval="2" program="ping -c1 -t1 192.168.1.60" score="1"/>
<heuristic interval="2" program="ping -c1 -t1 192.168.1.254" score="1"/>
</quorumd>
Start quorum disk daemon The daemon is also one of daemons automatically started by cman service qdiskd start Check quorum disk information
$ mkqdisk -L -d
mkqdisk v0.6.0
/dev/disk/by-id/scsi-1IET_00010002:
/dev/disk/by-uuid/55fbf858-df75-493b-a764-5640be5a9b46:
/dev/sdc:
Magic: eb7a62c2
Label: myqdisk
Created: Sat May 7 05:56:35 2011
Host: station2.example.com
Kernel Sector Size: 512
Recorded Sector Size: 512
Status block for node 1
Last updated by node 1
Last updated on Sat May 7 15:09:37 2011
State: Master
Flags: 0000
Score: 0/0
Average Cycle speed: 0.001500 seconds
Last Cycle speed: 0.000000 seconds
Incarnation: 4dc4d1764dc4d176
Status block for node 2
Last updated by node 2
Last updated on Sun May 8 01:09:38 2011
State: Running
Flags: 0000
Score: 0/0
Average Cycle speed: 0.001000 seconds
Last Cycle speed: 0.000000 seconds
Incarnation: 4dc55e164dc55e16
Status block for node 3
Last updated by node 3
Last updated on Sat May 7 15:09:38 2011
State: Running
Flags: 0000
Score: 0/0
Average Cycle speed: 0.001500 seconds
Last Cycle speed: 0.000000 seconds
Incarnation: 4dc4d2f04dc4d2f0
The cluster is still running with last node standing Please note Total votes=quorum votes=5=2+3, if quorum disk vote is less than (node votes+1), the cluster wouldn’t have survived
$cman_tool status
..
Nodes: 1
Expected votes: 9
Quorum device votes: 3
Total votes: 5
Quorum: 5
..
What is GFS? GFS allow all nodes to have direct CONCURRENT write access to the same shared BLOCK storage. For local file system e.g ext3, A shared BLOCK storage can be mounted in multiple nodes, but CONCURRENT write access is not allowed For NFS, the CONCURRENT write access is allowed, but it is not direct BLOCK device, which introduce delay and another layer of failure. GFS requirements: – A shared block storage (iSCSI, FC SAN etc.. ) – RHCS (Red hat Cluster suite) (although GFS can be mounted in standalone server without cluster, it is primarily used for testing purpose or recovering data when cluster fails) – RHEl 3.x onwards (RHEL derivatives: Centos/Fedora), it should work in other Linux distributions, since GFS and RHCS have been open sourced. GFS specifications: – RHEL 5.3 onwards use GFS2 – RHEl 5/6.1 supports maximum 16 nodes – RHEL 5/6.1 64 bit supports maximum file system size of 100TB (8 EB in theory) – Supports: data and metadata journaling, quota, acl, Direct I/O, growing file system online, dynamic inodes (convert inode block to data block) – LVM snapshot of CLVM under GFS is NOT yet supported. GFS components: RHCS components: OpenAIS, CCS, fenced, CMAN and CLVMD (Clustered LVM) GFS specific component: Distributed Lock Manager (DLM) Install RHCS and GFS rpms Luci (Conga project) is the easiest way to install and configure RHCs and GFS.
#GFS specific packages:
#RHEL 5.2 or lower versions
$yum install gfs-utils kmod-gfs
#RHEL 5.3 onwards, gfs2 module is part of kernel
$yum install gfs2-utils
Create GFS on LVM You can create GFS on raw device, but LVM is recommended for consistent device names and the ability to extend device
#Assume you have setup and tested a working RHCS
#Edit cluster lock type in /etc/lvm/lvm.conf on ALL nodes
locking_type=3
#Create PV/VG/LV as if in standalone system ONCE in any ONE of the nodes
#Start Cluster and clvmd on ALL nodes
#Better use luci GUI interface to start whole cluster
$Service cman start
$Service rgmanager start
$servcie clvmd start
#Create GFS ONCE in any ONE of the nodes
# -p lock_dlm is required in cluster mode. Lock_nolock is for standalone system
# -t cluster1:gfslv ( Real cluster-name: arbitrary GFS name )
# Above information is stored in GFS superblock, which can be changed with “gfs_tool sb” without re-initializing GFS e.g change lock type: "gfs_tool sb /device proto lock_nolock"
#-j 2: the number of journals, minimum 1 for each node. The default journal size is 128Mib, can be overridden by -J
#additional journal can be added with gfs_jadd
gfs_mkfs -p lock_dlm -t cluser1:gfslv -j 2 /dev/vg01/lv01
#Mount GFS in cluster member by /etc/fstab
#put GFS mount in /etc/fstab in ALL nodes
#NOTE:
#Cluster service can mount GFS without /etc/fstab after adding GFS as resource, but It can only mount on one node (the active node). Since GFS is supposed to be mounted on all nodes at the same time. /etc/fstab is a must, GFS resource is optional.
#GFS mount options: lockproto, locktable are optional, mount can obtain the information from superblock automatically
$cat /etc/fstab
/dev/vg01/lv01 /mnt/gfs gfs defaults 0 0
#Mount all GFS mounts
service gfs start
GFS command lines
####Check GFS super block
#some values can be changed by “gfs_tool sb”
$gfs_tool sb /dev/vg01/lv01 all
sb_bsize = 4096
sb_lockproto = lock_dlm
sb_locktable = cluster1:gfslv01
..
####GFS tunable parameters
#view parameters
gfs_tool gettune <mountpoint>
#set parameters
#The parameters don’t persist after re-mount, You can customize /etc/init.d/gfs to set tunable parameters on mounting
gfs_tool settune <mountpoint>
####Performance related parameters
#like other file system, you can disable access time update by mount option “noatime”
#GFS can also allow you to control how often to update access time
$gfs_tool gettune /mnt/gfs | grep atime_quantum
atime_quantum=3660 #in secs
#Disable quota, if not needed
#GFS2 remove the parameter and implement it in mount option “quota=off”
$gfs_tool settune /mnt/gfs quota_enforce 0
#GFS direct I/O
#Enable directI/O for database files, if DB has its own buffering mechanism to avoid “double” buffering
$gfs_tool setflag directio /mnt/gfs/test.1 #file attribute
$gfs_tool setflag inherit_directio /mnt/gfs/db/ #DIR attribute
$gfs_tool clearflag directio /mnt/gfs/test.1 #remove attribute
$gfs_tool stat inherit_directio /mnt/gfs/file # view attribute
#enable data journal for very small files
#disable data journal for large files
$gfs_tool setflag inherit_jdata /mnt/gfs/db/ #Enable data journal (only metadata has journal by default) on a dir. (if operate on a file, the file must be zero size)
###GFS backup, CLVM doesn't support snapshot
$gfs_tool freeze /mnt/gfs #change GFS to read-only (done once in any one of the nodes)
$gfs_tool unfreeze /mnt/gfs
###GFS repair
#after unmount GFS on all nodes
$gfs_fsck -v /dev/vg01/lv01 # gfs_fsck -v -n /dev/vg01/lv01 : -n answer no to all questions, inspect gfs only without making changes
GFS implementation scenarios:
GFS’s strength is the ability to do concurrent write to the same block device, It make it possible for Active-Active cluster nodes to write to the same block device, but there are few such cases in real life.
In Active-Active cluster nodes (all nodes perform the same task), RHCS can’t do load balancing itself, it requires external load balancer
– Database server cluster: In theory, all nodes can write to the same DB file concurrently, However, the performance will be degraded, because all nodes try to lock the file via Distributed Lock Manager. You can assign different task to cluster nodes to write to different DB file, e.g. node-A run DB-A and node-B run DB-B, but this can be done, without GFS, by mounting ext3 on individual iSCSI/FC disk.
GFS doesn’t lose to ext3 in above scenario, but its lack of LVM snapshot of in GFS‘s CLVMD kills my inspiration of using DB on GFS
– Application server cluster: e.g. Apache, Jboss server cluster. It is the true that GFS can simply application package deployment because all nodes can share the same application package binaries. But if you only use two nodes cluster, deploying application twice is not big hassle. Maintaining single copy of application binaries is convenient, but at risk of single point of failure.
– NFS Cluster: Because NFS is I/O bound, Why would you run Active-Active NFS cluster with CPU/memory resource in nodes are not being fully utilized?
GFS command lines
####Check GFS super block
#some values can be changed by “gfs_tool sb”
$gfs_tool sb /dev/vg01/lv01 all
sb_bsize = 4096
sb_lockproto = lock_dlm
sb_locktable = cluster1:gfslv01
..
####GFS tunable parameters
#view parameters
gfs_tool gettune <mountpoint>
#set parameters
#The parameters don’t persist after re-mount, You can customize /etc/init.d/gfs to set tunable parameters on mounting
gfs_tool settune <mountpoint>
####Performance related parameters
#like other file system, you can disable access time update by mount option “noatime”
#GFS can also allow you to control how often to update access time
$gfs_tool gettune /mnt/gfs | grep atime_quantum
atime_quantum=3660 #in secs
#Disable quota, if not needed
#GFS2 remove the parameter and implement it in mount option “quota=off”
$gfs_tool settune /mnt/gfs quota_enforce 0
#GFS direct I/O
#Enable directI/O for database files, if DB has its own buffering mechanism to avoid “double” buffering
$gfs_tool setflag directio /mnt/gfs/test.1 #file attribute
$gfs_tool setflag inherit_directio /mnt/gfs/db/ #DIR attribute
$gfs_tool clearflag directio /mnt/gfs/test.1 #remove attribute
$gfs_tool stat inherit_directio /mnt/gfs/file # view attribute
#enable data journal for very small files
#disable data journal for large files
$gfs_tool setflag inherit_jdata /mnt/gfs/db/ #Enable data journal (only metadata has journal by default) on a dir. (if operate on a file, the file must be zero size)
###GFS backup, CLVM doesn't support snapshot
$gfs_tool freeze /mnt/gfs #change GFS to read-only (done once in any one of the nodes)
$gfs_tool unfreeze /mnt/gfs
###GFS repair
#after unmount GFS on all nodes
$gfs_fsck -v /dev/vg01/lv01 # gfs_fsck -v -n /dev/vg01/lv01 : -n answer no to all questions, inspect gfs only without making changes
GFS implementation scenarios:
GFS’s strength is the ability to do concurrent write to the same block device, It make it possible for Active-Active cluster nodes to write to the same block device, but there are few such cases in real life.
In Active-Active cluster nodes (all nodes perform the same task), RHCS can’t do load balancing itself, it requires external load balancer
– Database server cluster: In theory, all nodes can write to the same DB file concurrently, However, the performance will be degraded, because all nodes try to lock the file via Distributed Lock Manager. You can assign different task to cluster nodes to write to different DB file, e.g. node-A run DB-A and node-B run DB-B, but this can be done, without GFS, by mounting ext3 on individual iSCSI/FC disk.
GFS doesn’t lose to ext3 in above scenario, but its lack of LVM snapshot of in GFS‘s CLVMD kills my inspiration of using DB on GFS
– Application server cluster: e.g. Apache, Jboss server cluster. It is the true that GFS can simply application package deployment because all nodes can share the same application package binaries. But if you only use two nodes cluster, deploying application twice is not big hassle. Maintaining single copy of application binaries is convenient, but at risk of single point of failure.
– NFS Cluster: Because NFS is I/O bound, Why would you run Active-Active NFS cluster with CPU/memory resource in nodes are not being fully utilized?
Disk Space issues
mpstat -P ALL
cat /proc/interrupts
iostat -kd 1 iostat -c -t iostat -c -t 2 10 iostat -c 3 iostat -d 5 iostat -x 1
sar -b
vmstat -S M 2 5
Find process causing high iowait
netstat -autpn | grep :80 netstat -autpn | grep :3306 netstat -na netstat -an|grep :80|sort|more netstat -an|grep ESTABLISHED netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -nr | more ps ax | awk ‘$3 ~ /^D/ { print $0 }’ netstat -an | grep :80 | wc -l
DO NOT DO THIS until you are certain what is going on.
echo 100 > /proc/sys/vm/inactive_clean_percent echo 2 10 20 > /proc/sys/vm/pagecache
16.5. HTTP Services HTTP session replication is used to replicate the state associated with your web clients on other nodes of a cluster. Thus, in the event one of your node crashes, another node in the cluster will be able to recover. Two distinct functions must be performed:
Session state replication
Load-balance of incoming invocations
State replication is directly handled by JBoss. When you run JBoss in the all configuration, session state replication is enabled by default. Just deploy your web application and its session state is already replicated across all JBoss instances in the cluster.
However, Load-balancing is a different story, it is not handled by JBoss itself and requires additional software. As a very common scenario, we will demonstrate how to setup Apache and mod_jk. This activity could be either performed by specialized hardware switches or routers (Cisco LoadDirector for example) or any other dedicated software though.
Note A load-balancer tracks the HTTP requests and, depending on the session to which is linked the request, it dispatches the request to the appropriate node. This is called a load-balancer with sticky-sessions: once a session is created on a node, every future request will also be processed by the same node. Using a load-balancer that supports sticky-sessions without replicating the sessions allows you to scale very well without the cost of session state replication: each query will always be handled by the same node. But in the case a node dies, the state of all client sessions hosted by this node are lost (the shopping carts, for example) and the clients will most probably need to login on another node and restart with a new session. In many situations, it is acceptable not to replicate HTTP sessions because all critical state is stored in the database. In other situations, loosing a client session is not acceptable and, in this case, session state replication is the price one has to pay.
Apache is a well-known web server which can be extended by plugging modules. One of these modules, mod_jk (and the newest mod_jk2) has been specifically designed to allow forward requests from Apache to a Servlet container. Furthermore, it is also able to load-balance HTTP calls to a set of Servlet containers while maintaining sticky sessions, and this is what is actually interesting for us.
16.5.1. Download the software First of all, make sure that you have Apache installed. You can download Apache directly from Apache web site at http://httpd.apache.org/. Its installation is pretty straightforward and requires no specific configuration. As several versions of Apache exist, we advise you to use version 2.0.x. We will consider, for the next sections, that you have installed Apache in the APACHE_HOME directory.
Next, download mod_jk binaries. Several versions of mod_jk exist as well. We strongly advise you to use mod_jk 1.2.x, as both mod_jk and mod_jk2 are deprecated, unsupported and no further developments are going on in the community. The mod_jk 1.2.x binary can be downloaded from http://www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/. Rename the downloaded file to mod_jk.so and copy it under APACHE_HOME/modules/.
16.5.2. Configure Apache to load mod_jk Modify APACHE_HOME/conf/httpd.conf and add a single line at the end of the file:
# Include mod_jk’s specific configuration file Include conf/mod-jk.conf Next, create a new file named APACHE_HOME/conf/mod-jk.conf:
# Load mod_jk module # Specify the filename of the mod_jk lib LoadModule jk_module modules/mod_jk.so # Where to find workers.properties JkWorkersFile conf/workers.properties
# Where to put jk logs JkLogFile 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 indicates to send SSK KEY SIZE JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories # JkRequestLogFormat JkRequestLogFormat “%w %V %T” # Mount your applications JkMount /application/* loadbalancer # You can use external file for mount points. # It will be checked for updates each 60 seconds. # The format of the file is: /url=worker # /examples/*=loadbalancer JkMountFile conf/uriworkermap.properties
# Add shared memory. # This directive is present with 1.2.10 and # later versions of mod_jk, and is needed for # for load balancing to work properly JkShmFile logs/jk.shm # Add jkstatus for managing runtime data <Location /jkstatus/> JkMount status Order deny,allow Deny from all Allow from 127.0.0.1 </Location> Please note that two settings are very important:
The LoadModule directive must reference the mod_jk library you have downloaded in the previous section. You must indicate the exact same name with the “modules” file path prefix.
The JkMount directive tells Apache which URLs it should forward to the mod_jk module (and, in turn, to the Servlet containers). In the above file, all requests with URL path /application/* are sent to the mod_jk load-balancer. This way, you can configure Apache to server static contents (or PHP contents) directly and only use the loadbalancer for Java applications. If you only use mod_jk as a loadbalancer, you can also forward all URLs (i.e., /*) to mod_jk.
In addition to the JkMount directive, you can also use the JkMountFile directive to specify a mount points configuration file, which contains multiple Tomcat forwarding URL mappings. You just need to create a uriworkermap.properties file in the APACHE_HOME/conf directory. The format of the file is /url=worker_name. To get things started, paste the following example into the file you created:
# Simple worker configuration file
# Mount the Servlet context to the ajp13 worker /jmx-console=loadbalancer /jmx-console/*=loadbalancer /web-console=loadbalancer /web-console/*=loadbalancer
This will configure mod_jk to forward requests to /jmx-console and /web-console to Tomcat.
You will most probably not change the other settings in mod_jk.conf. They are used to tell mod_jk where to put its logging file, which logging level to use and so on.
16.5.3. Configure worker nodes in mod_jk Next, you need to configure mod_jk workers file conf/workers.properties. This file specify where are located the different Servlet containers and how calls should be load-balanced across them. The configuration file contains one section for each target servlet container and one global section. For a two nodes setup, the file could look like this:
# Define list of workers that will be used # for mapping requests worker.list=loadbalancer,status
# Define Node1 # modify the host as your host IP or DNS name. worker.node1.port=8009 worker.node1.host=node1.mydomain.com worker.node1.type=ajp13 worker.node1.lbfactor=1 worker.node1.cachesize=10
# Define Node2 # modify the host as your host IP or DNS name. worker.node2.port=8009 worker.node2.host= node2.mydomain.com worker.node2.type=ajp13 worker.node2.lbfactor=1 worker.node2.cachesize=10
# Load-balancing behaviour worker.loadbalancer.type=lb worker.loadbalancer.balance_workers=node1,node2 worker.loadbalancer.sticky_session=1 #worker.list=loadbalancer
# Status worker for managing load balancer worker.status.type=status Basically, the above file configures mod_jk to perform weighted round-robin load balancing with sticky sessions between two servlet containers (JBoss Tomcat) node1 and node2 listening on port 8009.
In the works.properties file, each node is defined using the worker.XXX naming convention where XXX represents an arbitrary name you choose for one of the target Servlet container. For each worker, you must give the host name (or IP address) and port number of the AJP13 connector running in the Servlet container.
The lbfactor attribute is the load-balancing factor for this specific worker. It is used to define the priority (or weight) a node should have over other nodes. The higher this number is, the more HTTP requests it will receive. This setting can be used to differentiate servers with different processing power.
The cachesize attribute defines the size of the thread pools associated to the Servlet container (i.e. the number of concurrent requests it will forward to the Servlet container). Make sure this number does not outnumber the number of threads configured on the AJP13 connector of the Servlet container. Please review http://jakarta.apache.org/tomcat/connectors-doc/config/workers.html for comments on cachesize for Apache 1.3.x.
The last part of the conf/workers.properties file defines the loadbalancer worker. The only thing you must change is the worker.loadbalancer.balanced_workers line: it must list all workers previously defined in the same file: load-balancing will happen over these workers.
The sticky_session property specifies the cluster behavior for HTTP sessions. If you specify worker.loadbalancer.sticky_session=0, each request will be load balanced between node1 and node2. But when a user opens a session on one server, it is a good idea to always forward this user’s requests to the same server. This is called a “sticky session”, as the client is always using the same server he reached on his first request. Otherwise the user’s session data would need to be synchronized between both servers (session replication, see Section 16.5.5, “Configure HTTP session state replication”). To enable session stickiness, you need to set worker.loadbalancer.sticky_session to 1.
Note A non-loadbalanced setup with a single node required the worker.list=node1 entry before mod_jk would function correctly.
16.5.4. Configure JBoss Finally, we must configure the JBoss Tomcat instances on all clustered nodes so that they can expect requests forwarded from the mod_jk loadbalancer.
On each clustered JBoss node, we have to name the node according to the name specified in workers.properties. For instance, on JBoss instance node1, edit the JBOSS_HOME/server/all/deploy/jbossweb-tomcat50.sar/server.xml file (replace /all with your own server name if necessary). Locate the <Engine> element and add an attribute jvmRoute:
<Engine defaultHost=”localhost” jvmRoute=”node1″> … … </Engine> Then, for each JBoss Tomcat instance in the cluster, we need to tell it to add the jvmRoute value to its session cookies so that mod_jk can route incoming requests. Edit the JBOSS_HOME/server/all/deploy/jbossweb-tomcat50.sar/META-INF/jboss-service.xml file (replace /all with your own server name). Locate the <attribute> element with a name of UseJK, and set its value to true:
<attribute >true</attribute> At this point, you have a fully working Apache+mod_jk load-balancer setup that will balance call to the Servlet containers of your cluster while taking care of session stickiness (clients will always use the same Servlet container).
Note For more updated information on using mod_jk 1.2 with JBoss Tomcat, please refer to the JBoss wiki page at http://wiki.jboss.org/wiki/Wiki.jsp?page=UsingMod_jk1.2WithJBoss.
16.5.5. Configure HTTP session state replication In Section 16.5.3, “Configure worker nodes in mod_jk”, we covered how to use sticky sessions to make sure that a client in a session always hits the same server node in order to maintain the session state. However, that is not an ideal solution. The load might be unevenly distributed over the nodes over time and if a node goes down, all its session data is lost. A better and more reliable solution is to replicate session data across all nodes in the cluster. This way, the client can hit any server node and obtain the same session states.
The jboss.cache:service=TomcatClusteringCache MBean makes use of JBoss Cache to provide HTTP session replication service to the HTTP load balancer in a JBoss Tomcat cluster. This MBean is defined in the deploy/tc5-cluster-service.xml file.
Note If you are not running from the all configuration, session replication can be enabled by copying deploy/tc5-cluster-service.xml, lib/jgroups.jar and lib/jboss-cache.jar from server/all into your server configuration directory.
Below is a typical tc5-cluster-service.xml file. The configuration attributes in the TomcatClusteringCache MBean is very similar to those in Section 17.2, “JBossCache Configuration”.
<mbean code=”org.jboss.cache.TreeCache” >
<depends>jboss:service=Naming</depends> <depends>jboss:service=TransactionManager</depends>
<attribute > org.jboss.cache.JBossTransactionManagerLookup </attribute> <attribute >REPEATABLE_READ</attribute> <attribute >REPL_ASYNC</attribute> <attribute >Tomcat-Cluster</attribute> <attribute > … … </attribute> <attribute >15000</attribute> </mbean> The detailed configuration for the TreeCache MBean is covered in Section 17.2, “JBossCache Configuration”. Below, we will just example several attributes that are most relevant to the HTTP cluster session replication.
TransactionManagerLookupClass sets the transaction manager factory. The default value is org.jboss.cache.JBossTransactionManagerLookup. It expects to find the transaction manager under java:/TransactionManager.
IsolationLevel sets the isolation level for updates to the transactional distributed cache. The valid values are SERIALIZABLE, REPEATABLE_READ, READ_COMMITTED, READ_UNCOMMITTED, and NONE. These isolation levels mean the same thing as isolation levels on the database. The default isolation of REPEATABLE_READ makes sense for most web applications.
CacheMode controls how the cache is replicated. The valid values are REPL_SYNC and REPL_ASYNC, which determine whether changes are made synchronously or asynchronously. Using synchronous replication makes sure changes propagated to the cluster before the web request completes. However, synchronous replication is much slower. For asyncrhonous access, you will want to enable and tune the replication queue.
ClusterName specifies the name of the cluster that the cache works within. The default cluster name is Tomcat-Cluster. All the nodes should use the same cluster name. Although session replication can share the same channel (multicast address and port) with other clustered services in JBoss, replication should have it’s own cluster name.
ClusterConfig configures the underlying JGroups stack. The most import configuration elements are the muliticast adress and port, mcast_addr and mcast_port respectively, to use for clustered communication. These values should make sense for your network. Please refer to Section 17.1, “JGroups Configuration” for more information.
LockAcquisitionTimeout sets the maximum number of milliseconds to wait for a lock acquisition. The default value is 15000.
UseReplQueue determines whether to enable the replication queue when using asynchronous replication. This allows multiple cache updates to be bundled together to improve performance. The replication queue properties are controlled by the ReplQueueInterval and ReplQueueMaxElements properties.
ReplQueueInterval specifies the time in milliseconds JBoss Cache will wait before sending items in the replication queue.
ReplQueueMaxElements: specifies the maximum number of elements allowed in the replication queue before JBoss Cache will send an update.
16.5.6. Enabling session replication in your application To enable clustering of your web application you must it as distributable in the web.xml descriptor. Here’s an example:
<?xml version=”1.0″?> <web-app xmlns=”http://java.sun.com/xml/ns/j2ee“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd” version=”2.4″> <distributable/> <!– … –> </web-app> You can futher configure session replication using the replication-config element in the jboss-web.xml file. Here is an example:
<jboss-web> <replication-config> <replication-trigger>SET_AND_NON_PRIMITIVE_GET</replication-trigger> <replication-granularity>SESSION</replication-granularity> </replication-config> </jboss-web> The replication-trigger element determines what triggers a session replication (or when is a session is considered dirty). It has 4 options:
SET: With this policy, the session is considered dirty only when an attribute is set in the session. If your application always writes changed value back into the session, this option will be most optimized in term of performance. If an object is retrieved from the session and modified without being written back into the session, the change to that object will not be replicated.
SET_AND_GET: With this policy, any attribute that is get or set will be marked as dirty. If an object is retrieved from the session and modified without being written back into the session, the change to that object will be replicated. This option can have significant performance implications.
SET_AND_NON_PRIMITIVE_GET: This policy is similar to the SET_AND_GET policy except that only non-primitive get operations are considered dirty. For example, the http session request may retrieve a non-primitive object instance from the attribute and then modify the instance. If we don’t specify that non-primitive get is considered dirty, then the modification will not be replication properly. This is the default value.
ACCESS: This option causes the session to be marked as dirty whenever it is accessed. Since a the session is accessed during each HTTP request, it will be replicated with each request. The access time stamp in the session instance will be updated as well. Since the time stamp may not be updated in other clustering nodes because of no replication, the session in other nodes may expire before the active node if the HTTP request does not retrieve or modify any session attributes. When this option is set, the session timestamps will be synchronized throughout the cluster nodes. Note that use of this option can have a significant performance impact, so use it with caution.
The replication-granularity element controls the size of the replication units. The supported values are:
session: Replication is per session instance. As long as it is considered modified when the snapshot manager is called, the whole session object will be serialized.
attribute: Replication is only for the dirty attributes plus some session data, like, lastAccessTime. For session that carries large amount of data, this option can increase replication performance.
If your sessions are generally small, session is the better policy. If your session is larger and some partsare infrequently accessed, attribute replication will be more effective.
16.5.7. Monitoring session replication If you have deployed and accessed your application, go to the jboss.cache:service=TomcatClusteringCache MBean and invoke the printDetails operation. You should see output resembling the following.
/JSESSION
/quote
/FB04767C454BAB3B2E462A27CB571330 VERSION: 6 FB04767C454BAB3B2E462A27CB571330: org.jboss.invocation.MarshalledValue@1f13a81c
/AxCI8Ovt5VQTfNyYy9Bomw** VERSION: 4 AxCI8Ovt5VQTfNyYy9Bomw**: org.jboss.invocation.MarshalledValue@e076e4c8 This output shows two separate web sessions, in one application named quote, that are being shared via JBossCache. This example uses a replication-granularity of session. Had attribute level replication been used, there would be additional entries showing each replicated session attribute. In either case, the replicated values are stored in an opaque MarshelledValue container. There aren’t currently any tools that allow you to inspect the contents of the replicated session values. If you don’t see any output, either the application was not correctly marked as distributable or you haven’t accessed a part of application that places values in the HTTP session. The org.jboss.cache and org.jboss.web logging categories provide additional insight into session replication useful for debugging purposes.
16.5.8. Using Single Sign On JBoss supports clustered single sign-on, allowing a user to authenticate to one application on a JBoss server and to be recognized on all applications, on that same machine or on another node in the cluster, that are deployed on the same virtual host. Authentication replication is handled by the HTTP session replication service. Although session replication does not need to be explicitly enabled for the applications in question, the tc5-cluster-service.xml file does need to be deployed.
To enable single sign-on, you must add the ClusteredSingleSignOn valve to the appropriate Host elements of the tomcat server.xml file. The valve configuration is shown here:
<Valve className=”org.jboss.web.tomcat.tc5.sso.ClusteredSingleSignOn” />
|
|
Recent Comments