Apache + Tomcat 负载均衡 session复制
gavanwanggw
2024-10-01 08:33:33
原文
转自:http://blog.csdn.net/cssmhyl/article/details/8455400
http://snowolf.iteye.com/blog/743611
Apache 和 Tomcat原本就是一家,更是一家亲!
Apache与Tomcat整合,无非是将Apache作为前端依据请求路径、端口、代理分发给多个Tomcat,以到达转发和负载均衡的目的!同一时候。通过Apache和Tomcat相互作用,进行粘性会话,会话拷贝构建集群!这一切的最终结果就是“云服务”。不要说Session不重要,当下火爆的团购,假设离开Session还能快活多久?怎样保证Session同步。仍然是不能回避的问题!
/
BalancerMember http://192.168.49.1:8080/
</Proxy>
/
BalancerMember ajp://192.168.49.1:8009/
</Proxy>
/
BalancerMember ajp://192.168.49.1:8009/
</Proxy>
/zlex route=tomcat1
BalancerMember ajp://192.168.49.132:8009/zlex route=tomcat2
</Proxy>
对于windows系统,不须要考虑网络问题,广播地址(这里用到224.0.0.0和240.0.0.0)默认开放,对于linux则须要通过命令开放地址。
Ubuntu上开放广播地址(eth0网卡):
Shell代码

- sudo route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0
然后通过-v參数查看当前开放的广播地址:
Shell代码

- route -v

注意,重新启动后。该路由设置将丢失。
在Ubuntu下。能够考虑改动/etc/networks文件!
假设有必要。Windows上开放广播地址(192.168.49.128本机地址):
Cmd代码

- route add 224.0.0.0 mask 240.0.0.0 192.168.49.128
然后通过print參数查看当前开放的广播地址:
Shell代码

- route print

然后,改动tomcat的server.xml文件:
Shell代码

- sudo vi /etc/tomcat6/server.xml
在<Engine /> 节点中加入例如以下内容:
Xml代码

- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
- channelSendOptions="8">
- <Manager className="org.apache.catalina.ha.session.DeltaManager"
- expireSessionsOnShutdown="false"
- notifyListenersOnReplication="true"/>
- <Channel className="org.apache.catalina.tribes.group.GroupChannel">
- <Membership className="org.apache.catalina.tribes.membership.McastService"
- address="224.0.0.0"
- port="45564"
- frequency="500"
- dropTime="3000"/>
- <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
- address="192.168.49.1"
- port="4000"
- autoBind="100"
- selectorTimeout="5000"
- 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"/>
- </Channel>
- <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
- filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
- <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
- <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
- <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
- </Cluster>
这里须要注意<Membership />和Receiver:<Membership />节点的address属性是广播地址。Receiver节点的address属性是本地绑定地址。当然。默觉得auto。
因为我在启动Tomcat时,Tomcat频频将地址指向127.0.0.1。无奈仅仅好使用固定IP。
此外,为了减少Session复制的成本,Tomcat通过<Valve />节点。以过滤器的方式控制哪些请求能够忽略Session复制:
Xml代码

- <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
- filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
同一时候。在<Host>节点中加入例如以下内容:
Xml代码

- <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
- tempDir="/tmp/war-temp/"
- deployDir="/tmp/war-deploy/"
- watchDir="/tmp/war-listen/"
- watchEnabled="false"/>
在Tomcat的官方文档(Tomcat 6)中,对于<Deployer />节点的部署位置是错误的,通过观察Tomcat启动日志。确认该节点应当不属于<Host />节点中!
注意:Tomcat 6与Tomcat5在上述节点中使用的类包(包中名称由cluster变化为ha)有所不同。且结构有所调整。
先别急着重新启动,我们须要改动应用中的web.xml文件。将<distributable />节点部署到<web-app />节点中,开启分布式服务:

注意:假设没有设置该节点,SessionID将不能保持同步。不同的服务器将各自建立独立的SessionID!
监控Tomcat日志:
Shell代码

- tail -f /var/lib/tomcat6/logs/catalina.out
然后重新启动Tomcat1:
Shell代码

- sudo /etc/init.d/tomcat6 restart
观察日志:

注意两处红框:
第一处。Cluster启动,并绑定192.168.49.132:4000上。进行TCP通讯。并等待其它成员(Member)。
第二处,在管理器中注冊/zlex,绑定JvmRouteBinderValve。
至此。说明集群设置已经生效,但不能说明集群配置成功!
接着我们启动Tomcat2,观察其日志:
Cluster启动。并绑定192.168.49.128:4000上并发现成员[b]192.168.49.132![/b]
再看Tomcat1的日志:

Tomcat1发现其成员Tomcat2!这说明TCP通讯已建立。Tomcat成员能够进行Session同步!
同一时候,Tomcat成员直接会每隔一个时间段相互侦測/验证其它成员是否正常:

如今,開始訪问http://localhost/zlex。并不断刷新当前页面:
除了两处标识主机来源的tomcatX不同外。session是全然一致的!
提交一次改动。并不断刷新当前页:
假设细致观察,当前SessionID在不断交替变化,这说明负载均衡在起作用!
我们再来看看2个Tomcat后台日志都做了什么!
Tomcat1:
Tomcat2:
两仅仅猫都打印了同样的内容(a=1)不同的细节在于,sessionID带有服务器标识!
假设我们强行关闭Tomcat2:
首先,Tomcat1会非常快侦測到Tomcat2离线,因为这是TCP通讯。成员之间非常easy检測到其它成员是否离线!Tomcat1后台日志例如以下:

其次。Apache会侦測到Tomcat2发生异常。将其余请求转交给其它节点。即交由Tomcat1处理!
继续刷新http://localhost/zlex当前页面,耐心等待几秒。你会发现,即便再次刷新页面。sessionID仍旧绑定在标识tomcat1服务器上。
然后,我们恢复Tomcat2服务。Tomcat1会立即侦測到Tomcat2已经恢复正常:

最后。我们再次刷新当前页。Apache已经将请求分发给Tomcat2了,从后台日志能够看到session信息会非常快被同步了。
假设带有tomcatX标识的sessionID有非常多不便之处,能够关闭粘性会话。简单的讲。就是取消Tomcat中[b]server.xml中<Engine/ >节点的jvmRoute属性。[/b]然后。重新启动tomcat、apache!
页面提交一个b=3!

左边为Tomcat1,右边为Tomcat2。SessionID一致!
除了上述几种方案外,还有Terracotta模式。
一种第三方集群组件,2009年收购了缓存组件EhCache,能够结合Tomcat、JBoss等多种服务器,提供多种负载均衡、集群等功能实现,且当负载均衡节点超过8个时。仍然能够保持集群吞吐量的线性增长。
Eclipse插件地址:
http://download.terracotta.org/eclipse/update
下载地址:
http://www.terracotta.org/dl/oss-download-catalog
至此,Apache + Tomcat成功完毕,征服Apache系列暂告一段落。
作为开博以来的第100帖,算是非常成功了!