Apache2结合Tomcat6做LoadBalance+Cluster

 

转载自:http://blog.sina.com.cn/s/blog_53d27b3a01000ag3.html

 

负载均衡和集群是企业应用2 个重要的话题。有些人把他们混淆起来,虽然两件事情结合起来实现的是一个目的,就是提高企业应用程序的处理能力,但实际上是两件不同的工作,应用起来要根据具体情况进行处理。
早些年,可延展性作为J2EE吹嘘的一大法宝,各大厂商也纷纷提供各自的实现赚取高额的利润。但在实际应用上能起到多少作用,对于普通用户都是一个未知数,高额的代价就像一道不可逾越的高墙把多数用户隔在了墙外,而厂商则把守在墙头,一面吹嘘,一面收费。
在开源盛行的今天,多数技术都变得更加透明,我们甚至可以用完全开源的技术实现这个功能。
我做实验的版本是apache 2.0.55 + tomcat 6,apache是安装在Red Hat Linux 4E 上,tomcat 则是一个跑在linux上一个跑在windows上。
首先明确一下有关的概念,所谓负载均衡(loadbalance)所指的是,在服务器端短时间内获得大量的请求,单一服务器无法在一个较短的时间内相应这些请求,此时服务器需要一个机制,请求按照多个服务器不同的负载能力,把这些请求合理的分配。而集群(cluster)的作用则是在多个服务器之间共享用户信息,资源等。传统的做法是在集群的几个服务器之间完全共享用户会话信息,也就是说,同一个用户登陆以后,几个操作很可能是在不同的服务器上完成的,用户会话信息的任何变化都将在几个服务器上共享,在任何一个服务器上用户信息发生变化都需要通知其他服务器,称为服务器会话的同步复制。但事实证明这样的做法会因为复制用户信息损失大量的资源,性能也比较差。现在的做法是把特定的用户信息粘到特定的服务器上,同一个用户的操作都会在一台服务器上完成,有效避免了会话的复制操作,性能要明显高一些。
在apache和tomcat上如何配置上述服务,有不同的方法,比较通用的做法是在apache上加载mod_jk(我具体做的时候加载的是mod_jk2),通过加载这个模块,实现apache的负载均衡功能,就是请求合理分配到不同服务器上。在tomcat的host上配置cluster,实现整个host上的应用集群。

首先在apache上配置mod_jk2
我单独做了一个mod_jk的配置说明文件,在主配置中载入。在主配置文件中加入

include conf/jk.conf

新建一个jk.conf的文本文件,写入下面代码


#载入mod_jk2的模块
LoadModule jk2_module modules/mod_jk2.so
#设置mod_jk中的workers配置文件的位置
JkSet config.file /usr/local/apache2/conf/workers2.properties

根据tomcat文档中的范例,修改了相应的配置,形成下面workers2.properties文件
[logger]
level=DEBUG

[config:]
debug=0
debugEnv=0

[shm:]
info=Scoreboard. Requried for reconfiguration and status with multiprocess serve
rs.
file=anon

[workerEnv:]
info=Global server options
timing=1
debug=0

# 构造一个名称为lb的负载均衡配置
[lb:lb]

# 构造一个名字为 nb:8009的chanel,在下面可以覆盖主机地址和端口号
[channel.socket:nb:8009]
port=8009
host=130.120.2.248

[channel.socket:localhost:8109]
port=8109
host=localhost

# 定义ajp13的worker,名称为 nb:8009
[ajp13:nb:8009]
#前面定义的chanel
channel=channel.socket:nb:8009
#前面定义的负载均衡
group=lb

[ajp13:localhost:8109]
channel=channel.socket:localhost:8109
group=lb

# 配置uri转向,把/examples/开头的uri全部转向到负载均衡上处理
[uri:/examples/*]
group=lb
[status:]
info=Status worker, displays runtime information
#查看mod_jk上的配置和运行信息
[uri:/jkstatus/*]
info=The Tomcat /jkstatus handler
group=status:

通过上面配置,把两个tomcat的实例(一个在本地,一个在130.120.2.248上)配置到了一个名字为lb的负载均衡器上面。

然后配置tomcat上的cluster,我的做法是在host单元里面配置,当然也可以在引擎上配置,如果在引擎上配置则对引擎内所有配置的host都生效。
具体的工作是把下面的代码增加到tomcat主配置文件server.xml的Host单元中

< cluster  className = " org.apache.catalina.ha.tcp.SimpleTcpCluster "
                
  channelSendOptions = " 6 " >
<!--  这里需要说明一下的是channelSendOptions,这个参数说明了集群内部服务器消息的发送方式,实际上用了二进制数的表示方式,第一位是1说明使用ack(收到确认),第二位是1说明使用同步ack,第三位是1说明使用异步消息的模式,在这个配置的例子当中使用6=2+4,说明使用了同步ack的方式发送  -->
 
          
< manager  className = " org.apache.catalina.ha.session.BackupManager "
                  
  expireSessionsOnShutdown = " false "
                  
  notifyListenersOnReplication = " true "
                  
  mapSendOptions = " 6 " />
          
<!--
          就目前来说tomcat提供2种manager,一种是BackupManager,一种是DeltaManager,后者需要cluster的每个节点都严格部署了完全一样的同一个应用,会话被复制到了每一个服务器上    -->
       
          
< channel  className = " org.apache.catalina.tribes.group.GroupChannel " >
            
< membership  className = " org.apache.catalina.tribes.membership.McastService "
                        
address = " 228.0.0.4 "
                        
port = " 45564 "
                        
frequency = " 500 "
                        
dropTime = " 3000 " />
            
<!--  这里的地址228.0.0.4是一个默认的广播地址,只要是使用默认的广播地址的tomcat实例,均认为是工作在同一个cluster上,也就是说这些tomcat之间的会话会被复制 -->
            
< receiver  className = " org.apache.catalina.tribes.transport.nio.NioReceiver "
                      
address = " auto "
                      
port = " 5000 "
                      
selectorTimeout = " 100 "
                      
maxThreads = " 6 " />
 
            
< sender  className = " org.apache.catalina.tribes.transport.ReplicationTransmitter " >
              
< transport className = " org.apache.catalina.tribes.transport.nio.PooledParallelSender " />
            
</ sender >
            
< interceptor className = " org.apache.catalina.tribes.group.interceptors.TcpFailureDetector " />
            
< interceptor className = " org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor " />
            
< interceptor className = " org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor " />
          
</ channel >
 
          
< valve  className = " org.apache.catalina.ha.tcp.ReplicationValve "
                
  filter = " .*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt; " />
 
          
< deployer  className = " org.apache.catalina.ha.deploy.FarmWarDeployer "
                    
tempDir = " /tmp/war-temp/ "
                    
deployDir = " /tmp/war-deploy/ "
                    
watchDir = " /tmp/war-listen/ "
                    
watchEnabled = " false " />
 
          
< clusterlistener  className = " org.apache.catalina.ha.session.ClusterSessionListener " />
        
</ cluster >

其他配置项的说明可以查看tomcat的文档,都有详细的说明,这里需要说明的是我的2个tomcat实例都配置了相同的广播地址,保证了这两个tomcat在同一个集群上工作。

最后启动的时候需要注意

 

你可能感兴趣的:(apache,tomcat)