对于tomact的负载均衡,里面的问题很多都值得我们研究,这里我们不在讨论它的设置内容,而是讨论它的一些性能问题。这里面,我们主要重点说容错和session的相关知识。这也是为我们了解程序系统必须知道的内容。
◆Tomcat的负载均衡
先前版本的tomcat并没有提供负载均衡的能力。集成apache web server和tomcat servlet container就是一个不错的处理web请求的负载均衡集群。在Apache Tomcat中,被称为Tomcat Worker的Tomcat实例被配置来实现负载均衡。
Tomcat5提供三种方法来实现负载均衡:
分别是用JK本地连接器,用Apache2的mod_proxy和mod_rewrite,或者用balancer web app。
我们重点使用第三种,使用balancer web application来重定向web请求到集群内的各个节点。这个负载均衡的应用是基于规则的。使用servlet filter机制重定向进入的web请求到下一个有效的集群成员上。servlet filter在servlet2.3规范中有详细的介绍。过滤器(servletfilter)可以在web应用中负责多种不同的任务。例如JAAS认证,加密,记录日志和审核,数据压缩,XSLT过滤器转换XML内容等等。就如Tomcat均衡器网站讲述的那样,这个均衡器应用并非设计用来替代其他的强大的负载均衡机制。它用简单并且易于扩展的方法来重定向交易(traffic)到其他的服务器上。检查均衡器应用所提供的样例Java类,了解均衡器如何用不同的规则标准来完成各种不同的任务。
负载均衡配置文件(rules.xml)包含不同的规则和重定向的URLs。balancer filter检查Rule Chain来决定将请求重定向到那里,按照rules.xml中指定的顺序来检查规则。当一条规则匹配时,过滤器停止评估,并且重定向请求到规则指定的URL上。
◆容错
容错是系统的一种能力,能够做到系统中的一个服务器失效时,另一个有效的服务器能够接管,这对最终用户来讲是透明的。理想的情况是集群服务监测到集群内其中的一个服务器失效而不能处理请求时,停止发送请求到该服务器。然后周期性的检查集群中的该成员是否再次生效,如果生效,将再次将其添加到活动服务器节点池中。
◆Tomcat的容错
Tomcat5并没有提供一个内建的失败重启机制来检查集群成员的崩溃。希望,未来的版本能提供这个功能,用来发现集群内有效的机器,确定那些成员能处理进来的请求。
集群解决方案一般提供两种层次的失败重启能力:
请求层次的失败重启
如果集群中的一台服务器挂起,所有接下来的请求将会被重定向到集群中的其他服务器。这包含一种heart beat机制来保持跟踪服务状态和避免发送请求到没有回应的服务器上。在我们的集群设置中,一个Tomcat实例扮演着负载均衡器的角色,处理请求层次上的失败重启,并转发web请求到集群中的其他节点。
session层次的失败重启
一个web客户可以拥有一个由HTTP服务器维持的session。如果集群中的其中一台服务器挂起,集群中的另一台服务器能接手前一台服务器的session,保持连续性。这需要在集群内复制session数据。拥有session复制能力的Tomcat集群能处理session层次的失败重启。
◆session状态的持久化
失败重启和负载均衡都需要集群内不同的服务器之间能进行session状态的复制。当原来的服务器失败时,session状态复制允许客户无缝的从集群中的另外一台服务器上取得session信息。这个状态可以包括系统状态和/或应用状态(应用状态包含存储在HTTPsession中的对象和数据)。session复制的主要目的是当集群成员崩溃、为应用升级或者系统维护停止工作时能够不丢失任何session的内容。
谈到session的持续化,有一个简单的集群方案,集群成员不知道其他成员的session状态。在这个方案中,用户session完全在一台服务器上,由负载均衡器来选择。这叫做粘性session(或者叫sessionaffinity)。因此seesion数据保存在接收web请求的集群成员上。#p#
从另外一方面来将,集群可以以这样的一种方式实现,每一个集群成员完全明白其他成员的session状态,通过session状态的周期性传播到其他备用集群成员。这种session被称为复制session。
有三种方法实现session的持久化:
内存对内存的复制;
文件系统session持久化,session信息从一个中央文件系统读写;
数据库session持久化,session数据存储在一个JDBC数据存储器。
在内存session持久化中,当HTTPsession中的独立的对象改变,这个对象将会被序列化到其他的备用机器上,而在数据库session持续化中,当session中的任何对象改变时,session中的所有对象将被一起序列化。
数据库/文件系统session持续化的缺点是限制了当在HttpSession存储大型或大量对象时的可伸缩性。每一次用户增加一个对象到HttpSession中,session中所有的对象都会被序列化并被写到数据库或者共享文件系统中。
◆tomcat中的session复制
当前Tomcat版本的session复制是一种all-to-all的复制,即在任何时,session中的属性被传播到集群的所有成员。当集群小的情况下,这个算法是高效的,为应付大型集群的情况,Tomcat的下一个版本将提供主-从复制,session将仅仅被保存在一个或者两个备份服务器上。
在tomcat中,有三种类型的session复制机制:
内存中复制,使用Tomcat5自带的SimpleTcpCluster(在org.apache.catalina.cluster.tcp包中,文件为server/lib/catalina-cluster.jar);
session持久化,保存session在一个共享数据库上(org.apache.catalina.session.JDBCStore);
在共享的文件系统上保存session的状态(org.apache.catalina.session.FileStore,partofcatalina-optional.jar)。