前一篇介绍了nginx负载均衡tomcat集群,并通过tomcat自身实现了session的复制。这种方式实现的session同步存在缺陷:当一个节点的session数据发生变
化,要把整个session数据全部序列化,广播给其他节点,造成大量网络通信,导致网络阻塞。下面介绍通过Terracotta实现session的同步。
基本原理简介
一般利用Tomcat搭建Web应用集群有如下几种方法:
1、利用负载均衡器的粘session的方式把所有同一session的请求都发送到相同的Tomcat节点。这样不同用户的请求就被平均分配到集群中各 个tomcat节点上,实现负载均衡的能力。这样做的缺点是没有灾难恢复的能力。一旦一个节点发生故障,这个节点上所有的session信息全部丢失;
2、利用Tomcat session复制的机制使得所有session在所有Tomcat节点中保持一致。当一个节点修改一个session数据的时候,该节点会把这个 session的所有内容序列化,然后广播给所有其它节点。这样当下一个用户请求被负载均衡器分配到另外一个节点的时候,那个节点上有完备的 session信息可以用来服务该请求。这种做法的问题是对session哪怕有一点点修改,也要把整个sessions数据全部序列化 (serialize),还要广播给集群中所有节点,不管该节点到底需不需要这个session。这样很容易会造成大量的网络通信,导致网络阻塞。一般采 用这种方式,当Tomcat节点超过4个时候,整个集群的吞吐量就不能再上升了;
3、第三种方式是通过cookie保存用户信息的一个或几个关键字,每一个http请求到达web应用的时候,web程序拿这个关键字到数据库中读取相关 的数据,然后对其进行处理。也就是说把session数据保存到了数据库中。这样以来在内存中的session就完全不需要了。这样做的缺点就是加大了数 据库的负载,使得数据库变成了集群的瓶颈。而通过构造数据库集群提高负载能力往往需要高额的成本。
Terracotta的基本原理是对于集群间共享的数据,当在一个节点发生变化的时候,Terracotta只把变化的部分发送给Terracotta服 务器,然后由服务器把它转发给真正需要这个数据的节点。这样对网络的压力就非常小,各个节点也不必浪费CPU时间和内存进行大量的序列化操作。把这种集群 间数据共享的机制应用在session同步上,相当于对tomcat第二种集群实现机制进行了优化,既避免了对数据库的依赖,又能达到负载均衡和灾难恢复 的效果。在对比测试中,采用Terracotta搭建Tomcat集群,节点达到8个时候,整个集群的吞吐量还一直是线性增长的。
为了方便使用Terracotta搭建Tomcat集群,Terracotta提供了专门的插件tim-tomcat。下面用一台Terracotta服务器,两台Tomcat服务器做最简单的配置。
安装与配置
1、安装nginx1.5.4和Tomcat6.0.35,并作负载均衡配置(参照前一篇)2、从Terracotta官网下载terracotta-3.7.5.tar.gz,解压到/usr/local/terracotta
tar -zxvf terracotta-3.7.5.tar.gz
mv terracotta-3.7.5.tar.gz /usr/local/terracotta
3、配置Tomcat作为Terracotta客户端
复制/usr/local/terracotta/sessions/terracotta-session-1.3.5.jar、/usr/local/terracotta/common/terracotta-toolkit-1.6-runtime-5.5.0.jar这两个jar到Tomcat下lib目录。
编辑$Tomcat_Home/conf/context.xml
<Context>
<!-- 增加此配置 -->
<Valve className="org.terracotta.session.TerracottaTomcat60xSessionValve" tcConfigUrl="192.168.1.88:9510"/>
</Context>
如上是Tomcat6的配置方式,其他WebServer配置方式可见参考文档的具体说明。192.168.1.88为Terracotta服务器的ip,9510端口为Terracotta的通讯端口,另外默认9520为它的管理端口稍后用到。
4、启动服务进行测试
启动Terracotta
/usr/local/terracotta/bin/start-tc-server.sh &
启动Tomcat
/usr/local/Tomcat1/bin/startup.sh
/usr/local/Tomcat2/bin/startup.sh
启动nginx
/usr/local/nginx/sbin/nginx
用前一篇的测试页面进行测试,如果每次打开不同tomcat下的页面,且session id不变,说明session同步成功。
监控Terracotta状态
/usr/local/terracotta/bin/dev-console.sh
如图所示,Server Array中只有1个Terracotta服务器,Connected clients中有两个Tomcat。