详解Tomcat集群如何同步会话

2019-10-18 15:41:49丽君

为区分不同的动作必须要先定义好各种事件,例如会话创建事件、会话访问事件、会话失效事件、获取所有会话事件、会话增量事件、会话ID改变事件等等,实际上tomcat集群会有9种事件,集群根据这些不同的事件就可以彼此进行通信,接收方对不同事件做不同的操作。

如下图,例如node1节点创建完一个会话后,即向其他三个节点发送EVT_SESSION_CREATED事件,其他三个节点接收到此事件后则各自在自己本地创建一个会话,会话包含了两个很重要的属性——会话ID和创建时间,这两个属性都必须由node1节点跟着EVT_SESSION_CREATED一起发送出去,本地会话创建成功后即完成了会话创建同步工作,此时你通过会话ID查找集群中任意一个节点都可以找到对应的会话。同样对于会话访问事件,node1向其他节点发送EVT_SESSION_ACCESSED事件及会话ID,其他节点根据会话ID找到对应会话并更新会话最后访问时间,以免被认为是过期会话而被清理。类似的还有会话失效事件(同步集群销毁某会话)、会话ID改变事件(同步集群更改会话ID)等等操作。

这里写图片描述

Tomcat使用SessionMessageImpl类定义了各种集群通信事件及操作方法,在整个集群通信过程中就是按照此类定义好的事件进行通信,SessionMessageImpl包含的事件如下{ EVT_SESSION_CREATED、EVT_SESSION_EXPIRED、EVT_SESSION_ACCESSED、EVT_GET_ALL_SESSIONS、EVT_SESSION_DELTA、EVT_ALL_SESSION_DATA、EVT_ALL_SESSION_TRANSFERCOMPLETE、EVT_CHANGE_SESSION_ID、EVT_ALL_SESSION_NOCONTEXTMANAGER },除此之外它继承了序列化接口(方便序列化)、集群消息接口(集群的操作)、会话消息接口(事件定义及会话操作)。

这里写图片描述

集群增量会话管理器DeltaManager可以说是通过SessionMessageImpl消息来管理DeltaSession,即根据SessionMessageImpl里面的事件响应不同的操作。Tomcat的集群通信使用的是tribes组件(相关章节会对tribes组件详细分析),网络IO都交由tribes后应用可以更专注逻辑处理,DeltaManager存在一个messageDataReceived(ClusterMessage cmsg)方法,此方法会在本节点接收到其他节点发送过来的消息后被调用,且传入的参数为ClusterMessage类型,可转化为SessionMessage类型,然后根据SessionMessage定义的9种事件做不同处理。

其中有一个事件需要关注的是EVT_SESSION_DELTA,它是对会话增量同步处理的事件,某个节点在一个完整的请求过程中对某会话相关属性的所有操作被抽象到了DeltaRequest对象中,而DeltaRequest被序列化后会放到SessionMessage中,所以EVT_SESSION_DELTA事件处理逻辑就是从SessionMessage获取并反序列化出DeltaRequest对象,再将DeltaRequest包含的对某个会话的所有操作同步到本地该会话中,至此完成会话增量同步。