< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />
Apache&Tomcat集群
2010年五一晚上做的测试采用的软件:
1) apache_< xmlnamespace prefix ="st1" ns ="urn:schemas-microsoft-com:office:smarttags" />2.0.55-win32-x86-no_ssl.msi
2) apache-tomcat-5.5.29.zip
3) mod_jk
还有什么JDK了,操作系统了废话没用的就不提了。
1) 理论环节
先说下为什么要用Apache,用Apache的目的是为了做负载均衡。啥是个负载均衡?简单点说就是把请求你服务的数量分配开了,别让我一个人(是一个WEB服务器)来处理,大家一起来帮我处理,所以就产生了这么个名词,也由此就诞生了一种分配结构。画个图看看:
< xmlnamespace prefix ="v" ns ="urn:schemas-microsoft-com:vml" />
WEB服务器 |
WEB服务器A
|
WEB服务器B
|
WEB服务器C
|
前面一个领导后面一堆干活的,这个整体的事情叫负载均衡,前面的那个领导就是Apache大虾,此虾就是分配任务的头,有很多大虾都可以当此领导,Apache,nginx等等,Tomcat其实也可以的。用的最多是Apache,最厉害的是nginx,其实有它不均衡也可以了,哥们单挑支持3万并发连接,正好是Apache的10倍,据说新浪、网易、 腾讯都用它,可想而知。我还没验证过,大家没事telnet下三个大网站看看是不是。Tomcat用在这有点笨,分配任务的时候据说没原则,领导的领导们不好控制他所以用的人少。
2) Apache操作
现在开始来实现负载均衡的操作:
i. 先装apache_2.0.55
选这版本是因为用的人多,网上资料把我决定了(版本很重要,待会儿告诉你为什么),毕竟学别人的东西。
ii. 配置
a) 在http.conf最后加一句:include conf/mod_jk.conf
b) 创建mod_jk.conf,并添加内容
以下是我配置的原样:()
LoadModule jk_module modules/mod_jk.so #加载mod_jk Module
JkWorkersFile conf/workers.properties #指定 workers.properties文件路径
JkMount /* controller #对所有的请求进行分流
c) 创建workers.properties文件,并添加内容
以下内容是我配置的原样本:按此段第二条的的配置位置创建
worker.list = controller,tomcat1,tomcat2 #server 列表
#========tomcat1========
worker.tomcat1.port=8888 #ajp13 端口号,在tomcat下server.xml配置,默认8009
worker.tomcat1.host=localhost #tomcat的主机地址,如不为本机,请填写ip地址
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor = 1 #server的加权比重,值越高,分得的请求越多
#========tomcat2========
worker.tomcat2.port=9999 #ajp13 端口号,在tomcat下server.xml配置,默认8009
worker.tomcat2.host=localhost #tomcat的主机地址,如不为本机,请填写ip地址
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor = 1 #server的加权比重,值越高,分得的请求越多
#========controller,负载均衡控制器========
worker.controller.type=lb
worker.controller.balanced_workers=tomcat1,tomcat2 #指定分担请求的tomcat
worker.controller.sticky_session=1
d) mod_jk.so文件
这个文件就是本段第一句在http.conf中首先设置的内容。到Apache那下载, 它是The Apache Tomcat Connector,就是Tomcat和别的服务器连接的插件,这类插件有很多种,有连IIS、Sun、apache,netscape等。其实下载的不叫mod_jk.so叫mod_jk-apache-2.0.55.so,我下的时候只有最新的mod_jk-1.2.30-httpd-2.2.3.so,为了配合版本的问题,百度了个2.0.55的。
把这个文件放置到此段第二条的的配置的位置
iii. 补充阐述
现在说下版本的问题,最关键的是什么版本的mod_jk能支持你采用的Apache,且又和你选的Tomcat配套。因为我直接下了个最新的Tomcat5.529的,Tomcat Connector 提供的是mod_jk-1.2.30-httpd-2.2.3.so,实验的时候折腾了1个小时都没成功,Apache就是启动不了。换了个2.0.55的,还是启动不了,最后发现是一句汉语注释没有加“#“,害的我死劲的读apache的英语模板,学了半天英语。
还有就是把下载的连接器改名为mod_jk.so。
You should first have mod_jk.so (unix) or mod_jk.dll (Windows) installed in your Apache module directory (see your Apache documentation to locate it)
其实改不改无所谓,就是王八的屁股,叫‘龟腚’!,造做就好懒的管它为什么。
忘了说那个workers.properties文件了,那个文件很好理解,猜猜就可以了猜不错。就是让领导的领导(说白了就是我或者你)配置领导下面有那些干活的和哪些活由谁来干的,Apache的Quick Start讲的很清楚,高级需求时再看看。
举例:
JkMount /*.jsp tomcat1 就是说所有请求的是jsp文件的tomcat1搞定。
JkMount /*.do tomcat2 就是说把所有.do请求的交给tomcat2处理。
JkMount /* controller 就是说领导按照一定比例随机分配给下面干活的,这个"controller"就是在workers.propertise里指定的负载分配控制器。
3) TOMCAT操作
i. 安装Tomcat
把下载的解压版本解压一份,按住ctrl点击后拖一下,两份改改名,Ta/Tb
ii. 配置Server.xml
改端口:要启多个Tomcat需要改的端口改了再说:
Ta |
端口功能 |
Tb |
<Server port="9005" |
关闭使用端口 |
<Server port="8005" |
<CONNECTOR port="9080" |
http使用端口 |
<CONNECTOR port="8090" |
<CONNECTOR port="8888" |
Apache通讯端口 |
<CONNECTOR port="9999" |
到此Apache的工作就结束了,也就是说后台可以有多个兄弟们帮你干活了。
1) 理论环节
什么是集群,这里的集群主要说的是会话集群。举个例子好比打日本人一样:中国有两个团(A团和B团),小日本部队一来,A团就知道他们是哪个部队(假如鸠山由纪夫来了),B团也知道他们是哪个部队了,为什么呢?因为中央(就是Apache)已经明确告诉A团去处理下,弄死倭寇。A团就特别高兴,很炫耀的把这个消息告诉B团了,来者是鸠山由纪夫。
集群说的其实就是最终这个功效,大家是一个集体,来的这个敌人我清楚你也清楚。很明显把鸠山由纪夫来了这个事情复制到B团,也就是复制了一份Session, 福田康夫来了也一样他的session也会被大家一起知道。
个人感觉叫集群有点不合适,就是Session的同步,假如你程序里用到了Application,不知道是什么情况,有时间验证下。
2) 技术环节
i. 主要配置server.xml
a) 把<Cluster></Cluster>这个结点的注释去掉。
b) 修改Ta的tcpListenPort="4001" Tb的tcpListenPort="4002"就OK了。
ii. 补充方法
a) 默认法
我看了Tomcat的文档,里面给出了好几种策略,研究了下,最快最稳的就是用默认,不用去掉<Cluster></Cluster>结点的注释,直接新加一句:
<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster" defaultMode="true" />
b) 细节说明
Tomcat的维机百科说的很多,都是一些疑问性的内容,如:在Windos without network 的情况下要设置mcastBindAddress="127.0.0.1"(默认228.0.0.4),linux加上路由route add -host 228.0.0.4 dev eth0 *,重点就是那么几个属性,Tomcat的文档比我讲的还明白。
c) Engine元素
这个元素的那个属性我没有实验,因为网友们已经声名有问题,以下原文:
在这两个Tomcat的以下结点添加jvmRoute属性:
<ENGINE name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
<ENGINE name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
然而实际我配置的时候还不能加jvmRoute属性,配置了反而有问题。刷新浏览器窗口总是在某一个tomcat控制台输出形如 :
SessionID:154678FA6D4D0ABD57658B750E7A3532.tomcat1 (在tomcat1窗口)
或者
SessionID:3800571A532AECEA7280F45361861AD4.tomcat2 (在tomcat2窗口)
由控制台打印的结果可以看出,SessionID在哪个tomcat上产生,那么后续该会话的请求将总是会这个tomcat来处理。并且注意到SessionID的形式比通常情况多了一个后缀.tomcat1或.tomcat2,还搞不清楚是为什么。
我实验得出这个是由session是不是可粘贴而控制的,就是那个workers.properties文件的:worker.controller.sticky_session=true或者false控制。
以上的集群配置就算完成!
1) 测试工程
某个工程如果要使用集群必须要在它的Web.xml文件上加上<distributable/>结点
2) A团离线
我测试两个Tomcat都配置好了以后,正常集群的情况下,如果一个离线,另一个完全正常接管后面的程序处理,Session不会出问题,其他的访问什么都没问题。
离线后重新上线,启动后大约在20秒内所有的Session都可以正常同步完成。
3) 其他问题
主要是Tomcat提示的问题:
确定所有节点拥有相同的时间, 并且通过网络时间服务(NTP)同步操作系统的时间!
你的所有会话属性值必须实现java.io.Serializable,Session
应该是已经序列化了,要不然怎么复制的,没注意过它的源码,有三种复制的方法Tomcat Doc说很好,咋这种就是内存的COPY。注意
appBase一定要指向webapps,把webapps/ROOT删除,但动态页面路径会出问题,网络上传说的。
URL从外面看必须是相同的,其实就是说的两个Tomcat的集群工程应该是完全一样的
4) 遇到的问题
使用的端口多了,经常出现被占的情况。我配的时候UUSee经常和我抢端口。
解决办法:netstat �Cano
参数o 是说看的时候列出进程的PID,查到pid后任务管理器,选择出PID这个列,就是知道是什么进程了, Kill掉就可以了。
5) jvmRoute名称
两个Tomcat配置文件Host节点的域名配置必须一样,server.xml中的jvmRoute名称必须和worker.properties中的tomcat实例名称一致,不然无法实现session_stricky。
如果不想实现粘性session, jvmRoute可以不配制。
如果不想实现session复制,Cluster配制的注释就无需去掉
6) 分工问题
worker.loadbalancer.sticky_session=false,true表示会话具有粘性。意味着用户和1开始会话,以后用户从浏览器A发出的请求只要处于同一个会话中,负载均衡器就会始终让1来处理请求。这时候,集群不会进行会话复制。默认为false。前者为false,时候,后者的设置没什么影响。如果前者为true,后者也为true时候,表示始终连接。比如1异常终止,那么,服务端会返回500的错误。False的话,就发给2了,有可能不存在会话信息。
7) 网卡问题
集群中的tomcat服务器之间使用组播的形式来通信。如果tomcta所在的机器上有多个网卡,或者配置了虚拟网卡,有可能导致组播失败,从而复发复制会话。比如,tomcat1已经启动,tomcat2出现信息:
No members activein cluster group
一上信息表明,2没有识别到1,组播失败。这是,应该在cluste的membership的配置中,确保设置了如下bind属性,它用于明确地设置组播绑定地址:
<Membership className="org.apache.catalina.tribes.membership.McastService"
bind="127.0.0.1"
address="228.0.0.4" 。。。。。>
8) 路由问题
出现这个错误:Error receiving mcast package (errorCounter=10). Try Recovery!
是路由问题。server.xml加mcastBindAddress="127.0.0.1"。如果加了ROUTE ADD 那么就要去掉这行mcastBindAddress="127.0.0.1"
9) 最后
tcpListenAddress="127.0.0.1" 要是多个tomcat在不同机器上就改这里。
大“工”告成 !还没有写总结,写了技术文档了。
转自:http://kzpkzp.blog.163.com/blog/static/16869581820105132580272/