【集群的概念】
集群(cluster)指的是一组计算机通过通信协议连接在一起的计算机群,它们能够将工作负载从一个超载的计算机迁移到集群中的其他计算机上,这一特性称为负载均衡(load balancing),它的目标是使用主流的硬件设备组成网格计算能力,达到、甚至超过天价的超级计算机的计算性能。
1、集群顾名思意是一群计算机构成的集合。
2、它们之间要相互通信,通信的目的是:保持应用的一致性。应用的一致性包括应用数据的一致性呵应用操作的一致性。
(程序=数据+操作; 操作一致性只要两个代码完全一样就可以了,当然如果应用程序在线升级要保持操作一致性可能比较困难。数据一致性,主要就是指状态信息,比如HttpSession。集群中多个节点间如何做到状态信息一致?一般的方法:a,采用分布式Session服务器,各个节点都从Session服务器上存取数据,这种方法实现简单,但是Session服务器容易形成单点。不过我们可以对Session服务器做集群,比如用memcached做session服务器。b,session复制,就是让集群中的各个节点把自己的HttpSession信息通过session复制的通信协议相互广播给其他成员。实现复杂,但是能HA。 另外,早期可能会采用sticky session的方式,也就是route all requests from the same session to the same server,这种方式有个问题是如果这个被route的服务器宕机,就不能做到HA了。)
3、特征:负载均衡;高可用。
Load-balancing when multiple computers are linked together to share computational workload or function as a single virtual computer.
Logically, from the user side, they are multiple machines, but function as a single virtual machine.
Requests initiated from the user are managed by, and distributed among, all the standalone(独立的) computers to form a cluster.
This results in balanced computational work among different machines, improving the performance of the cluster system.
(多台计算机通过网络相互连接以分摊负载,但是就用户而言,功能上表现为一台“被虚拟的”高性能的超级计算机。用户的请求被前面的“前导器LoadBalancer”分发到集群中的任何一台计算机。负载均衡集群运行时一般通过一个或者多个前端负载均衡器将工作负载分发到后端的一组服务器(Server Farm)上,从而达到整个系统的高性能和高可用性。这样的计算机集群有时也被称为服务器群。)
【集群的目标: 利用集群技术将一些普通的PC虚拟成一个高性能的超级计算机】
(scale-up vs. scale-out)
scale-up 不但成本高,而且效果不好; scale-out 成本低,而且效果好。
典型的超级计算机生产厂商包括IBM、SGI,以及其他一些大学、科研组织,以IBM Blue Pacific超级计算机为例,它拥有5800 个处理器来计算核反应的物理模拟过程,这样的计算机价格对于绝大部分商业用户是很难承受的,而且要面临很多的技术和维护问题,并且换代成本也很高,升级能力差。因此,发展了利用通信技术连接其他计算机,组成一个网格计算系统,可以分配负载的工作给其他计算机的CPU进行处理的解决方法来模拟超级计算机的能力。目前很多超级计算机也是通过集群技术得到的,特别是近年,名列世界Top500的超级计算机多数指集群系统,集群计算已经是比较成熟技术,但它仍在继续发展着。
【实验】
前导器httpd(服务口子:80)
后面跟两个Tomcat构成集群: tomcatBBS和tomcatBlog,其中:
(1)tomcatBBS
a: 启动的口子
8005口子,用于shutdown;
8080口子,http口子;
8009口子,AJP口子,用于接收来自httpd前导器分发的请求;
4001口子,用于接收集群中其他成员的Session复制相关信息。
b: 在server.xml中加个属性 jvmRoute=tomcatBBS
c: 在web.xml中加成 <distrutable /> 利用自带的Example/Session测试
(2)tomcatBlog
a: 启动的口子
9005口子,用于shutdown;
9080口子,http口子;
9009口子,AJP口子,用于接收来自httpd前导器分发的请求;
4002口子,用于接收集群中其他成员的Session复制相关信息。
b: 在server.xml中加个属性 jvmRoute=tomcatBBS
c: 在web.xml中加成 <distrutable /> 利用自带的Example/Session测试
配置文件:
在httpd前导器上的配置
(1)httpd.config
#the coming item jk_module was added by [email protected] on 2009-06-30
LoadModule jk_module modules/mod_jk-1.2.28-httpd-2.2.3.so
JkWorkersFile conf/workers.properties
#
# Configure mod_jk
#
#JkMount /*.* lbcontroller
JkMountFile conf/uriworkermap.properties
JkLogFile logs/mod_jk.log
JkLogLevel debug
(2)workers.properties
#下面是分发控制器 注意不要放tomcat实例
worker.list=lbcontroller,jkmonitor
#Tomcat1实例配置 这里要和Tomcat配置文件Service.xml的jvmRoute保持一致
worker.tomcatBBS.host=127.0.0.1
worker.tomcatBBS.port=8009
worker.tomcatBBS.type=ajp13
#分发权重 值越大负载越大
worker.tomcatBBS.lbfactor = 1
#tomcatBlog实例配置
worker.tomcatBlog.host=127.0.0.1
worker.tomcatBlog.port=9009
worker.tomcatBlog.type=ajp13
#分发权重 值越大负载越大
worker.tomcatBlog.lbfactor = 1
#负载均衡分发控制器
worker.lbcontroller.type=lb
worker.lbcontroller.balanced_workers=tomcatBBS,tomcatBlog
#不采用sticky_session方式,而采用session复制方式来保持状态一致性
worker.lbcontroller.sticky_session=false
#JK监控
worker.jkmonitor.type=status
(3)uriworkermap.properties
/*=lbcontroller
/jkstatus=jkmonitor
#/*=DLOG4J
#/jkstatus=status
#!/*.gif=DLOG4J
#!/*.jpg=DLOG4J
#!/*.png=DLOG4J
#!/*.css=DLOG4J
#!/*.js=DLOG4J
#!/*.htm=DLOG4J
#!/*.html=DLOG4J
在tomcatBlog上的配置(tomcatBBS类似)
<?xml version='1.0' encoding='utf-8'?>
<Server port="9005" shutdown="SHUTDOWN">
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="9080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="9009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatBlog">
<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="4002"
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"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</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>
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>
</Engine>
</Service>
</Server>
访问地址:
http://localhost/examples/servlets/servlet/SessionExample
Sessions Example
Session ID: A92757C6486E78F3DADFC2F03F898539.tomcatBBS (注:尽管带了.tomcatBBS,但是tomcat在request.getSession()时,只会依据 A92757C6486E78F3DADFC2F03F898539从HttpSessionContext中找到session对象,后缀.tomcatBBS是会被忽略的,这就是为什么要在server.xml中加jvmRoute=tomcatBBS的原因。 )
Created: Thu Jul 02 16:51:45 CST 2009
Last Accessed: Thu Jul 02 17:02:51 CST 2009 The following data is in your session:
BBS = BBSValue
Blog = BlogValue
【参考文献】
1、http://zyycaesar.iteye.com/blog/296606 Tomcat集群Cluster实现原理剖析
2、http://zyycaesar.iteye.com/blog/296501 Tomcat集群成员间1对多的通信是依靠IP组播;
3、http://blog.sina.com.cn/s/blog_4b4cb069010009jm.html~type=v5_one&label=rela_prevarticle
Tomcat 5集群中的SESSION复制
4、http://blog.sina.com.cn/s/blog_50edbc1601008qzb.html J2EE集群原理
5、http://lxiaodao.iteye.com/blog/321000 Tomcat session复制详细配置过程一
6、http://hi.baidu.com/luodaijun/blog/item/5bbe4cfb5ffef864034f56a1.html/index/1#comment Tomcat session复制详细配置过程二(一步步教你怎么配)
7、http://www.theserverside.com/tt/articles/article.tss?l=J2EEClustering 英文
=====================================================================
=====================================================================
Running more than one Web site on one computer is called virtual hosting.
Fully Qualified Domain Name (FQDN):host name+domain name.
e.g. www.wrox.com host name: www domain name:wrox.com
www.wrox.com是由一个web server来提供服务的。
例如:domain name为wrox.com可以还有其它的hosts,例如:p2p.wrox.com, newsletter.wrox.com等。
实现virtual host的两种方式:
(1)IP-based virtual hosts
一个host上通过multihoming hosts或者virtual network interfaces实现
(2)Name-based virtual hosts
根据http request header来判断是请求哪个domain
但是SSL要求唯一的ip地址,所以secure web不能用这种方式
1.建立多个tomcat instance所对应的目录,每个instance包含conf,logs,temp,webapps,work
2.每个instance启动脚本,和shutdown脚本都指定了变量CATALINA_BASE到建立的machine目录
CATALINA_HOME指定tomcat的目录
3.为每个tomcat instance所对应的server.xml配置文件,指定Server port,AJP Connector port
4.为server.xml中的Engine指定jvmRoute,对于参加load-balancing的instance,这个值是唯一的。该值需要和Apache Server’s mod_jk’s worker.properties中的值一致。
worker.<worker name>.<property> = <property value> <worker name>==jvmRoute
5.为web应用的web.xml设置<distributable/>,则该web application的session是共享的。
504
6.下载apache http server并安装
$ ./configure –prefix=PREFIX
$ make
$ make install
7.httpd -D DUMP_MODULES,看是否安装了proxy_module (shared),proxy_ajp_module (shared),proxy_balancer_module (shared)
8.如果没有,则通过apxs命令建立mod_proxy_ajp,mod_proxy,mod_proxy_balancer相对应的module
./apxs -a -i -c ../../httpd-2.2.11.src/modules/proxy/mod_proxy.c ../../httpd-2.2.11.src/modules/proxy/proxy_util.c
./apxs -a -i -c ../../httpd-2.2.11.src/modules/proxy/mod_proxy_ajp.c ../../httpd-2.2.11.src/modules/proxy/ajp*.c
./apxs -a -i -c ../../httpd-2.2.11.src/modules/proxy/mod_proxy_balancer.c
并且注意httpd.conf中定义的LoadModule的顺序
正向代理forward proxy:intermediate server that sits between the client and the origin server
客户端向proxy发送请求,以origin server为目标。
A reverse proxy (or gateway)对于客户端来说,仅是一个web server,发送请求到该server,然后reverse proxy来决定请求的发送情况。
如果proxy所在的host可以通过http://example.com/访问,则通过配置
ProxyPass /mirror/foo/ http://backend.example.com/
说明请求该proxy的请求http://example.com/mirror/foo/bar,则被映射到origin server的http://backend.example.com/bar
负载均衡:
apache http server支持的负载均衡算法
3 load balancer scheduler algorithms available for use: Request Counting, Weighted Traffic Counting and Pending Request Counting
问题日志:
[Mon Mar 30 15:11:58 2009] [warn] proxy: No protocol handler was valid for the URL /. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.
需要mod_proxy_http.c
将http换成ajp协议
<Proxy balancer://mycluster>
BalancerMember ajp://127.0.0.1:8009 route=machine1
BalancerMember ajp://127.0.0.1:8109 route=machine2
BalancerMember ajp://127.0.0.1:8209 route=machine3
</Proxy>
ProxyPass / balancer://mycluster/
需要指定route=machine1,,才能够告诉http server哪样的session value到哪个tomcat instance上
10.共享session
Cluster It uses regular multicast (heartbeat packets) to determine membership
cluster利用hartbeat包来决定membership
Nodes within the same cluster listen to and multicast at the same multicast address and port.
同一cluster内的节点,对于同一multicast地址进行监听和multicast
Nodes that do not multicast within a required dropTime are considered dead and are removed from the cluster (until they start multicasting again).
在dropTime到期之后,如果节点不进行multicast,则认为是dead的,就会从cluster中被移除。直到再次multicast之后,才加进来
The membership listens for the multicast and manages the set of current nodes in the cluster dynamically.
Session replication requests and session updates are sent between member nodes in the cluster.
两个节点之间相互发送session复制,session更新请求。
BackupManager sends data to a backup node
<Cluster>可以放到<Engine>或者<Host>内。
前者是多个context,后者是一个context
<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.8″ bind=”192.168.23.2″
port=”45564″
frequency=”500″
dropTime=”3000″/>
<Receiver className=”org.apache.catalina.tribes.transport.nio.NioReceiver”
address=”192.168.23.2″
port=”4200″
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=”.*\.gif;.*\.js;.*\.jpg;.*\.htm;.*\.html;.*\.txt;”/>
<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>
The channelSendOptions value is used by the DeltaManager only
The Apache Tribes framework provides the following services:
(1)Membership service based on multicast heartbeat and TCP failure detection; dynamically determines the members in a group.
This service determines and maintains information on the machines that are considered part of the group (cluster) at any point in time.
(2)Reliable messaging service between the different members of a group, providing a range of message delivery guarantees.
Receiver:This component receives the replicated data information from other members.
The filter attribute of the replication Valve may be used to override and stop session replication for specific matching requests.