Apache+Tomcat集群
来源:互联网 发布:mindmap mac 编辑:程序博客网 时间:2024/06/04 18:11
一、集群环境搭建
仔细阅读网上关于搭建集群的系列博客就能完成集群的搭建,进过集群的搭建,有几个个人心得:
1、apache的版本要注意,我这里使用的是httpd-2.2.25-win32-x86-no_ssl.msi 下载地址如下:http://www.apache.org/dist/httpd/binaries/win32/
不同版本的apache,可能配置存在一定的差异
2、注意博客中的这句话:继续下拉文档找到Include conf/extra/httpd-vhosts.conf,去掉前面的注释符。
3、参与集群的tomcat的各个端口,建议有规律的选择
4、搭建好的服务,将通过apache的80端口进行访问,根据负载均衡策略选择不同的tomcat。此时由于80端口是默认端口,所以可以直接通过127.0.0.1/应用名的方式访问
5、通过环回地址可以访问的集群,未必能通过真实ip地址访问,因为80端口是默认的http端口,可能涉及防火墙的问题,所以本地调试时,可以直接使用127.0.0.1进行
推荐博客:http://zyycaesar.iteye.com/category/50540,
总结:apache负责负载均衡,tomcat负责session的拷贝。 Apache官网API手册:http://tomcat.apache.org/tomcat-6.0-doc/api/overview-summary.html
待深入的点:
1、session的共享策略:<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>,这是tomcat自带的最简单的共享方案,还有哪些方案?如何自己写一个?
2、在集群环境下,除了session,普通的类的全局唯一性如何保证?比如类锁不再唯一?使用商业解决方案,如Terracotta?还是?
二、应用集群会带来的问题和应对策略
在分布式或者集群环境下,传统的方案,很多情况下都会不行,比如单例、静态变量、缓存、session等,这些机制一旦移植到集群环境下,就会无法正常工作,此时需要考虑如何实现全局共享唯一的目标,方案主要有三种:
第一种:对于较小的数据,比如用户登录人数,可以直接保存到数据库中
第二种:对于较大的数据,直接操作数据库成本太高,需要考虑使用全局缓存,encache会是一个比较好的选择,它是一个分布式缓存框架
第三种:对于session这种,可以通过广播的方式实时同步到各个节点,确保数据全局一致且全量,当然,这种实现起来较为复杂,通常是由web服务器的厂商提供,如tomcat的SimpleTcpCluster
当然,除了上面三种比较重要的场景,还有一些其他的场景,可以阅读下文:http://blog.163.com/l_gx396696760/blog/static/39228229201082510172650/
三、HttpSession在分布式下的解决方案
对于WEB应用集群的技术实现而言,最大的难点就是如何能在集群中的多个节点之间保持数据的一致性,会话(Session)信息是这些数据中最重要的一块。 要实现这一点,大体上有两种方式,
一、 把所有Session数据放到一台服务器上或者数据库中,集群中的所有节点通过访问这台Session服务器来获取数据;
二、 在集群中的所有节点间进行Session数据的同步拷贝,任何一个节点均保存了所有的Session数据。
两种方式都各有优点,
第一种方式简单、易于实现,但是存在着Session服务器发生故障会导致全系统不能正常工作的风险;第二种方式可靠性更高,任一节点的故障不会对整个系统对客户访问的响应产生影响,但是技术实现上更复杂一些。 大部分厂商都选择用第二种方式实现,默认的session在不同节点间的同步,通过tcp协议传输session对象,基于NIO实现
下面就介绍下tomcat是如何按照第二种方法实现session在集群多个节点间同步的:
当采用tomcat默认集群配置(<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>)时,配置的细节实际上被省略了,
对于大多数应用而言,使用默认配置已经足够,完整的默认配置应该是这样:
<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="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
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=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<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.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
tomcat集群各节点通过建立tcp链接来完成Session的拷贝,拷贝有同步和异步两种模式。在同步模式下,对客户端的响应必须在Session拷贝到其他节点完成后进行;异步模式无需等待Session拷贝完成就可响应。异步模式更高效,但是同步模式可靠性更高。同步异步模式由channelSendOptions参数控制,默认值是8,为异步模式,4是同步模式。在异步模式下,可以通过加上拷贝确认(Acknowledge)来提高可靠性,此时channelSendOptions设为10。
Manager用来在节点间拷贝Session,默认使用DeltaManager,DeltaManager采用的一种all-to-all的工作方式, 即集群中的节点会把Session数据向所有其他节点拷贝,而不管其他节点是否部署了当前应用。当集群中的节点数量很多并且部署着不同应用时,可以使用BackupManager,BackManager仅向部署了当前应用的节点拷贝Session。 但是到目前为止BackupManager并未经过大规模测试,可靠性不及DeltaManager。
Channel负责对tomcat集群的IO层进行配置。Membership用于发现集群中的其他节点,这里的address用的是组播地址,使用同一个组播地址和端口的多个节点同属一个子集群,因此通过自定义组播地址和端口就可将一个大的tomcat集群分成多个子集群。关于Channel的编程模型,请参见http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/tribes/Channel.html。
Receiver用于各个节点接收其他节点发送的数据,在默认配置下tomcat会从4000-4100间依次选取一个可用的端口进行接收,自定义配置时, 如果多个tomcat节点在一台物理服务器上注意要使用不同的端口。
Sender用于向其他节点发送数据,具体实现通过Transport配置
PooledParallelSender是从tcp连接池中获取连接,可以实现并行发送,即集群中的多个节点可以同时向其他所有节点发送数据而互不影响。
Interceptor有点类似下面将要解释的Valve,起到一个阀门的作用,在数据到达目的节点前进行检测或其他操作,如TcpFailureDetector用于检测在数据的传输过程中是否发生了tcp错误。
Valve用于在节点向客户端响应前进行检测或进行某些操作,
ReplicationValve就是用于用于检测当前的响应是否涉及Session数据的更新,如果是则启动Session拷贝操作,filter用于过滤请求,如客户端对图片,css,js的请求就不会涉及Session, 因此不需检测,默认状态下不进行过滤,监测所有的响应。
JvmRouteBinderValve会在前端的Apache mod_jk发生错误时保证同一客户端的请求发送到集群的同一个节点,tomcat官方文档并未解释如何实现这一点,而且笔者认为这一设置似乎并无多大实用性。
Deployer用于集群的farm功能,监控应用中文件的更新,以保证集群中所有节点应用的一致性, 如某个用户上传文件到集群中某个节点的应用程序目录下,Deployer会监测到这一操作并把这一文件拷贝到集群中其他节点相同应用的对应目录下以保持所有应用的一致。 这是一个相当强大的功能,不过很遗憾,tomcat集群目前并不能做到这一点,开发人员正在努力实现它,这里的配置只是预留了一个接口。
Listener用于跟踪集群中节点发出和收到的数据,也有点类似Valve的功能。
在大体了解了tomcat集群实现模型后,就可以对集群作出更优化的配置了,tomcat推荐了一套配置,使用了比DeltaManager更高效的BackupManager,并且对ReplicationValve设置了请求过滤,注意在一台服务器部署多个节点时需要修改Receiver的侦听端口,另外,为了更高效的在节点间拷贝数据,所有tomcat节点最好采用相同的配置,具体配置如下:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="6">
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<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"/>
<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.MessageDispatch15Interceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.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>
Tomcat集群除了可以进行Session数据的拷贝,还可进行Context属性的拷贝,通过修改context.xml的Context配置可以实现,使用<Context className="org.apache.catalina.ha.context.ReplicatedContext"/>替换默认Context即可,当然也可再加上distributable="true"属性。
下面通过假想的一组场景来描述tomcat集群如何工作,集群采用默认配置,由t1和t2两个tomcat例程组成,场景按照时间顺序排列。
1. t1启动
t1按照标准的tomcat启动,当Host对象被创建时,一个Cluster对象(默认配置下是SimpleTcpCluster)也同时被关联到这个Host对象。
当某个应用在web.xml中设置了distributable时,Tomcat将为此应用的上下文环境创建一个DeltaManager。
SimpleTcpCluster启动membership服务和Replication服务(用于建立tcp连接)。
2. t2启动(待t1启动完成后)
首先t2会执行和t1一样的操作,然后SimpleTcpCluster会建立一个由t1和t2组成的membership。
接着t2向集群中已启动的服务器即t1请求Session数据,如果t1没有响应t2的拷贝请求,t2会在60秒后time out。
在Session数据拷贝完成之前t2不会接收客户端的http或mod_jk/ajp请求。
3. t1接收http请求,创建Session s1
t1正常响应客户请求,但是在t1把结果发送回客户端时,ReplicationValve会拦截当前请求(如果filter中配置了不需拦截的请求类型,这一步就不会进行,默认配置下拦截所有请求),
如果发现当前请求更新了Session,调用Replication服务建立tcp连接把Session拷贝到membership列表中的其他节点即t2,
返回结果给客户端(注意,如果采用同步拷贝,必须等拷贝完成后才会返回结果,异步拷贝在数据发送到tcp连接就返回结果,不等待拷贝完成)。
在拷贝时,所有保存在当前Session中的可序列化的对象都会被拷贝,而不仅仅是发生更新的部分。
4. t1崩溃
当t1崩溃时,t2会被告知t1已从集群中退出,然后t2就会把t1从自己的membership列表中删除,
发生在t2的Session更新不再往t1拷贝,同时负载均衡器会把后续的http请求全部转发给t2。
在此过程中所有的Session数据不会丢失。
5. t2接收s1的请求
t2正常响应s1的请求,因为t2保存着s1的所有数据。
6. t1重新启动
按步骤1、2一样的操作启动,加入集群,从t2拷贝所有Session数据,拷贝完成后开放自己的http和mod_jk/ajp端口接收请求。
7. t1接收请求,s1失效
t1继续接收来自s1的请求,把s1设置为过期。
这里的过期并非因为s1处于非活动状态超过设置的时间,而是执行类似注销的操作而引起的Session失效。
这时t1并非发送s1的所有数据而是一个类似s1 expired的消息,t2收到消息后也会把s1设为过期。
8. t2接收请求,创建Session s2
和步骤3一样。
9. t1 s2过期
对于因超时引起的Session失效t1无需通知t2,因为t2同样知道s2已经超时。
因此对于tomcat集群有一点非常重要,所有节点的操作系统时间必须一致!
不然会出现某个节点Session已过期而在另一节点此Session仍处于活动状态的现象。
- apache+tomcat负载集群
- apache&tomcat集群
- Apache+JK+Tomcat 集群
- Apache tomcat 集群
- apache与tomcat集群
- Apache+tomcat集群
- apache tomcat 集群
- apache与tomcat集群
- tomcat+apache+linux集群
- Apache+Tomcat 集群
- apache tomcat 集群
- apache+tomcat集群配置
- Apache+tomcat集群
- Apache+Tomcat集群配置
- Apache+Tomcat集群配置
- apache + tomcat集群
- 配置Apache+Tomcat集群
- apache+tomcat 集群
- 从主机名谈真实Hadoop集群与虚拟机集群管理
- PM面试
- 那些可以在数据库里做的事:分页与过滤
- MyElipse 快捷键大全
- UIResponder学习
- Apache+Tomcat集群
- 隐藏对话框和单文档窗体
- HP-UX使用swinstall安装时报错
- java中十进制转二进制转换函数
- git gitignore文件配置
- Linux下防火墙开启相关端口及查看已开启端口
- ios 抓图实现
- html5+Jquery mobile+phoneGAP开发混合程序实战记录(及疑难)
- item15: 在资源管理类中提供对原始资源的访问