示例
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="6">
<Manager className="org.apache.catalina.ha.session.BackupManager"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<!--
<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="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"
bind=“192.168.22.1”/>
<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.MessageDispatchInterceptor"/>
<Interceptor
className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*.gif|.*.js|.*.jpeg|.*.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>
详解
Cluster
此元素可以配置在 <Engine> 或者 <Host> 中。className 是集群类,目前仅有 org.apache.catalina.ha.tcp.SimpleTcpCluster 可用。channelSendOptions 是 Tribes 通信框架消息发送选项,可以设置为0x0002 (确认发送),0x0004 (同步发送) ,0x0008 (异步发送)以及它们的逻辑或运算结果,默认是8,如果希望异步发送且确认发送结果,那么设置为2+8=10。对于 SimpleTcpCluster 类或者调用 SimpleTcpCluster.send 方法的对象,它们所发出的每一个消息上都附加着一个 channelSendOptions 标志。DeltaManager 使用 SimpleTcpCluster.send 方法发送消息,而 BackupManager 则直接通过 channel 来发送。
Manager
会话管理器配置,可以配置在 <Cluster> 中或者 <Context> 中,后者会覆盖前者的配置。以前每个 web.xml 中配置了 <distributable/> 的应用都必须使用同样的 manager,而如今不同了,我们可以为每个应用定义一个 manager类,从而在集群中混合多个 manager。显然,A 节点上的某个应用的manage 必须与 B 节点上的同样应用的 manager 相同。如果没有为应用指定 manager,而且该应用被标识为 <distributable/>,Tomcat 就会采取 <Cluster> 中的配置。className 是集群会话管理器类,有 BackupManager 和 DeltaManage 两种可选。expireSessionsOnShutdown 设置为 true 时,一个节点关闭,将导致集群下的所有 Session 失效。如果希望当集群中的 Tomcat 节点上复制或删除会话属性时通知会话监听器就设置 notifyListenersOnReplication 为 true。mapSendOptions 为6表示 BackupManager 同步发送消息,参考 <Cluster> 的 channelSendOptions。
Channel
Channel 元素是 Tribes 架构的一个重要组成部分,Tribes 是 Tomcat 内部所使用的分组通信架构。Channel 元素封装了所有通信相关事项。
Mermbership
每个节点都要维护一份集群节点信息列表,集群组通知的默认实现是在使用 UDP 数据包发送组播心跳到组播IP地址的基础上构建的。集群成员通过使用相同的多播地址/端口组合组合在一起,每个成员定时发送用于动态发现组成员的心跳,frequency 就是发送心跳时间间隔。如果在一个 dropTime 时间内没有收到某个心跳,那么这个心跳所属节点就会从当前节点维护的节点列表删除。frequency 和 dropTime 的单位都是毫秒。
address 属性是所用的组播地址,port 是所用的组播端口号。这两项组合起来将集群隔离开。如果你希望一个 QA 集群和一个生产集群,最简单的方法就是将 QA 集群的组播地址和端口号不同于生产集群的组播地址和端口号组合。bind参数用于多网卡的主机,组播不跨网段因此多网卡最好设置,否则容易出错,默认值是0.0.0.0,表示要用ip等于bind的值的网卡发送和接收组播数据包。如果是Linux系统,一般还需要加JVM环境变量-Djava.net.preferIPv4Stack=true,否则会出错。
Reciver
接收器,在 Tribes 架构中,数据的发送与接收以及被拆分为两种功能性组件了。正如其名所示,Receiver 负责接收信息。由于 Tribes 与线程无关(其他架构也开始采用这一种常见改进了),该组件内部包含一个线程池,设定有maxThreads 和 minThreads 两种参数。address 是节点地址,port 是节点端口,两者包含在心跳中被发送到其他节点,节点之间通过 TCP 协议通信。address 设置为 auto 的时候值是 java.net.InetAddress.getLocalHost().getHostAddress(),因此多网卡的节点最好直接写 IP 地址,否则会造成 TCP 通信失败。 接收器分为 BioReceiver (阻塞式)和 NioReceiver (非阻塞式),selectorTimeout 表示 NioReceiver 内轮询的超时时间,单位毫秒,默认是5000。
Sender
发送器,Sender 组件负责将消息发送给其他节点的 Reciver。Sender 含有一个 shell 组件 ReplicationTransmitter,但真正所要完成的任务则是通过子组件 Transport 来完成的。Transport 分为两种,bio.PooledMultiSender (阻塞式)和 nio.PooledParallelSender(非阻塞式) 。由于 Tribes 支持一个 Sender 池,所以消息可以使用 NIO 发送器并行的发送。
Interceptor
Tribes 利用了一个堆栈传送消息。每个堆栈内的元素都被称为拦截器。使用拦截器,逻辑可被分成更容易管理的代码段。
TcpFailureDetector 通过TCP验证崩溃的成员,如果组播数据包丢失,这个拦截器可以防止误报为崩溃。比如,某个节点会被标记为崩溃,尽管它还在运行,此时这个拦截器就可以发现这个节点还在运行,防止误报为崩溃节点。
MessageDispatchInterceptor 查看 Cluster 组件发送消息的方式是否设置为Channel.SEND_OPTIONS_ASYNCHRONOUS(Cluster标签下的channelSendOptions为8时)。
如果是,这个拦截器先将等待发送的消息进行排队,然后将排好队的消息转给 Sender。
ThroughputInterceptor 输出对流量的简单统计。
请注意,拦截器的顺序很重要。在 server.xml 中定义的顺序正是它们出现在 channel 堆栈中的顺序。这种机制就像是链表,最前面的是第一个拦截器,末尾的是最后一个拦截器。
Value
可以理解为 Tomcat 的拦截器。集群使用 valve 来跟踪针对 Web 应用的请求。<Cluster> 元素本身并不是 Tomcat 管道的一部分,集群将 valve 添加到了它的父容器上,比如说 <Cluster> 元素被配置到 <Engine> 元素中,那么 valve 就会被加到 <Engine> 元素中。
ReplicationValve 将在 HTTP 请求结束的最后通知集群,以便集群可以做出是否要复制数据的决策。filter属性意思是,对于已知的文件扩展或url,您可以使用该 Value 通知集群,会话未被修改,属性值是 java.util.regex 正则表达式。
Deployer
默认的 Tomcat 集群支持耕种部署(farmed deployment),比如说集群可以在其他的节点上部署和取消部署应用。该组件的状态目前还不稳定,但我们很快就会解决这个问题。所以暂时不要用。
ClusterListener
在使用DeltaManager时,消息将由集群对象接收,并通过该侦听器传到DeltaManager