需求需要这样的一个web服务器:既能处理jsp,php,asp,cgi等多种脚本页面,同时要具有集群、负载均衡等功能。其次,现在一个公网ip地址非常宝贵,往往需要在一个ip地址上提供多个站点服务。
为此,有必要将asp,jsp,php 等整合在同一个web服务器中,并实现more web per IP功能。我之前只用过IIs 和tomcat,对其他的最多只是了解而不熟悉,更谈不上用过。突然面对这样一个需求,不知道从何下手。在师傅的指导和百度了N下之后,决定采用apache+tomcat+iasp+php来整合实现。
这里我主要介绍下tomcat与apache的整合,因为在这一块上,花了我很长时间。从查看百度和其他一些论坛上的文章,然后照例自己动手修改、测试,到从头阅读apache官方文档,然后再修改、再测试,一工花了我整整四个工作日。四天就那样一直无聊地修该、测试,测试、修改,再测试、再修改... 还好最终成功了,否则我要疯了。
回头来看,其实很简单,关键是博客、论坛里面的文章不权威,有的实例确实可能正确,但是不知道他们为什么要那么做,而为什么不这么做,还有些文章则完全就是为了资源而分东拼西凑忽悠人。受骗之后决定去从头阅读官方英文文档,然后再做测试,这才是对我测试成功的最大帮助。
现在开始重点。tomcat与apache整合,实现负载均衡、tomcat集群功能的必要性:tomcat主要是为Java而写,它能处理JSP以及servlet,但是它在处理静态页面、.jpg,.gif等静态文件上却永不如apache。如果把所有web元素都抛给tomcat来处理,当数据量庞大的时候,tomcat就会显得迟钝,僵死。整合后,可以让tomcat来处理jsp文件,其他的静态文静则由apache来处理。对于访问量很大的网站,一个tomcat已经不能承担,它需要多个tomcat来协助处理数据,即需要负载均衡、tomcat集群。而tomcat集群还有个好处是当你与之初建立起会话的tomcat失去链接或者是该故障tomcat死机之后,你的业务会平稳地飘到集群中其他的tomcat上去执行,而不会丢失数据。
下面将是详细的配置,先是一步步地完成 apache+tomcat整合,负载均衡、tomcat集群功能,然后在给出了一个我测试成功的综合实例。这既是我自己忙了几天后的总结,贴出来也是跟大家分享,希望对需要的人有点帮助。 其次,通过这之后,我觉得也建议大家看东西最好还是先看官方文档,那才是最全面,最权威的东西,其他都是浮云。
万能WEB服务器整合笔记
一环境:
Windows 7/windows server 2008
Jdk(java_ee_sdk-6u1-jdk-windows.exe)
Tomcat(apache tomcat6.0.18.ZIP)(免安装包,只需配置环境变量)
Apache(httpd-2.2.17-win32-x86-no_ssl.msi)
Jk(mod_jk-1.2.31-httpd-2.2.3.so)(同时下载相同jk版本的source文件)
Jk的源文件(tomcat-connectors-1.2.31-src.zip)
二首要工作
1. 安装JDK,并配置环境变量(path= %java_home%/bin;%java_home%/jre/bin; classpath=%java_home%/lib/dt.jar; %java_home%/lib/tools.jar)
2. 安装tomcat。解压apache tomcat6.0.18.ZIP 到安装目录,配置环境变量(classpath= %tomcat_home%/bin;)
3. 安装apache
安装完后分别测试,确保tomcat、apache都能正常运行。
三 JSP的整合
一 tomcat+jk+apache 整合
(以我的安装目录为例来讲。Apache:D:/Apache2.2 Tomcat:D:/apache-tomcat-6.0.18)
步骤:
1. 分别解压jk的安装包和资源包,将安装包下的xxx.so文件重命名为mod_jd.so并复制到D:/Apache2.2/manual文件夹中。将资源包下面conf文件夹下面的httpd-jk.conf、worker.properties文件复制到D:/Apache2.2/conf文件夹中。
2. 打开D:/Apache2.2/conf 目录下的apache配置文件httpd.conf,在文件中找到Include conf/extra/httpd-vhosts.conf 代码,并将其前面的注释去掉(去掉#)。
3. 打开D:/Apache2.2/conf/extra目录下的httpd-vhosts.conf文件,在文件中找到NameVirtualHost *:80代码,然后在其上面一行添加代码:Include conf/httpd-jk.conf(既把这个文件加载进去)。再在该文件的最后添加一个VirtualHost ,代码如下:
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.storm.com #可以随便写
DocumentRoot "C:/www/zcglxt" #工程目录
ServerName www.zcglxt.com #访问站点的域名
ServerAlias 172.31.10.168 #域名别名
ErrorLog "logs/dummy-host2.storm.com-error.log" #日志文件
CustomLog "logs/dummy-host2.storm.com-access.log" common #日志文件
# All requests go to tomcat1 by default
JkMount /* tomcat1 #tomcat1是随后workers.properties文件中的一实例
# JkMount /* tomcat1 表示把所有请求都抛给tomcat1处理
# Serve html, jpg and gif using httpd
JkUnMount /*.html tomcat1
# JkUnMount /*.html表示所有的.html都不抛给tomcat1,由Apache自己处理。
JkUnMount /*.jpg tomcat1
JkUnMount /*.gif tomcat1
<Directory "C:/www/zcglxt">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
4. 打开D:/Apache2.2/conf中的workers.properyies文件,在第一行未注释的代码前面添加如下代码:worker.list=tomcat1
worker.tomcat1.type=ajp13
worker.tomcat1.host=localhost
worker.tomcat1.port=8009
5.打开D:/apache-tomcat-6.0.18/conf目录下的server.xml文件,在</host>后面再添加一个虚拟机: <Host name="www.zcglxt.com" appBase="zcglxt"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="c:/www/zcglxt" debug="0" reloadbale="true"/>
</Host>
6.修改主机映射文件:用文本编辑器打开C:/Windows/System32/drivers/etc中的hosts文件,添加映射:127.0.0.1 www.zcglxt.com (这样做就可以用域名 www.zcglxt.com来访问站点)
7.在c:/www/zcglxt目录下放一个web工程(至少包含一个.jsp和一个.html文件),分别用http://www.zcglxt.com、http://www.zcglxt.com:8080 访问.jsp,.html页面。只启动apache时,只可以访问.html文件,访问.jsp文件时会报503错误,这是合理的的。同时启动apache和tomcat,所有文件都能访问,且用80端口和8080端口访问的页面显示的效果应该是一样的。
注释及注意事项
1:
在配置过程中httpd-jk.conf文件没做任何修改,这是因为我们在把jk文件拷贝到D:/Apache2.2/manual文件中时把名字修改成了:mod_jk.conf .
Httpd-jk.conf中的主要代码如下:
LoadModule jk_module modules/mod_jk.so #加载mod_jk.so
<IfModule jk_module>
JkWorkersFile conf/workers.properties #加载workers.properties
# Our JK error log
# You can (and should) use rotatelogs here
JkLogFile logs/mod_jk.log #添加日志文件,便于排错
# Our JK log level (trace,debug,info,warn,error)
JkLogLevel info
# Our JK shared memory file
JkShmFile logs/mod_jk.shm
</IfModule jk_module>
2.
Workers.properties文件中的worker是用来连接tomcat和apache通信的中间件,上面配置了一个实例tomcat1:
worker.list=tomcat1
worker.tomcat1.type=ajp13
worker.tomcat1.host=localhost
worker.tomcat1.port=8009
ajp是tomcat与apache通信的协议,13是版本号。localhost表示与本机的tomcat通信,可以设成具体的ip地址。8009是tomcat中ajp协议的默认端口。这个可以在tomcat的配置文件server.xml文件中看到。这两处的端口必须一致。
3
在配置tomcat中的虚拟机时, <Context path="" docBase="c:/www/zcglxt" debug="0" reloadbale="true"/>中的path必须是path=””,而不能是path=”/”,否则会报错。
4.配置apache中的虚拟机时,为了安全,官方建议先默认把所有请求都抛给tomcat,然后再用JkUnMount 排除需要由apache助理的文件。其次在配置apache中的虚拟机时还必须配置<Directory "C:/www/zcglxt">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
这段是用于权限控制,如果不加,则会报403错:you don’t hava permission to access/on this server。
二.负载均衡
(前提:apache与tomcat已整合成功)
步骤:
1. 打开D:/Apache2.2/conf中的workers.properties文件 ,找到代码段:
将8109改为8009,并且在后面再添加一行代码变为:
worker.balancer.balance_workers=node1
worker.node1.reference=worker.template
worker.node1.host=localhost
worker.node1.port=8009
worker.tomcat1.lbfactor =1
继续往下找到node2代码段:
worker.balancer.balance_workers=node2
worker.node2.reference=worker.template
worker.node2.host=localhost
worker.node2.port=8209
并将其代码段改为:
worker.balancer.balance_workers=node2
worker.node2.reference=worker.template
worker.node2.host=172.31.8.58
worker.node2.port=8009
worker.node2.lbfactor =1
2. 在apache中添加或者修改原有虚拟主机(tomcat中的虚拟机也要做相应修改或添加, 这里略)
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.storm.com
DocumentRoot "C:/www/test"
ServerName www.test.com
ServerAlias 172.31.10.168
ErrorLog "logs/dummy-www.test.com.log"
CustomLog "logs/dummy-www.test.com.log-access.log" common
# All requests go to worker1 by default
JkMount /* balancer
#balancer也是一个workers实例,但它的type不是ajb,而是lb。(别急下面会讲到。)
# Serve html, jpg and gif using httpd
JkUnMount /*.html balancer
JkUnMount /*.jpg balancer
JkUnMount /*.gif balancer
<Directory "C:/www/test" >
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
3. 同时启动本机的tomcat和173.31.8.58上的tomcat,用www.test.com(需要在hosts中配置映射)访问站点,可以看到程序在本机tomcat和172.31.8.58上来回执行。
注释及注意事项。在默认的worders.properties文件中已经实例化了一个worker (balancer)用来实现负载均衡。主要代码如下:
worker.list=balancer
worker.balancer.type=lb (类型为lb,)
worker.balancer.balance_workers=node1 (参与实现负载的成员node1)
worker.node1.reference=worker.template
worker.node1.host=localhost (node1所在主机)
worker.node1.port=8009
worker.balancer.balance_workers=node2(参与实现负载的成员node2)
worker.node2.reference=worker.template (采用继承来定义成员的type等属性)
worker.node2.host=172.31.8.58 (node2所在主机)
worker.node2.port=8009
worker.template.type=ajp13 (type为ajp13,既用来处理请求的workers)
worker.template.socket_keepalive=true
worker.template.ping_mode=A
… …
上面的node1,node2 都是具体的workers, 与整合例子中的tomcat1是一种性质的。他们可以在开始就声明 :worker.list=node1,node2(官方文档上说多个worker可以用“,”隔开,但是我实际用的时候报错,还是得分开写worker.list=node1 worker.list=node2),只是当这些worker只用与负载均衡时,则可以不声明,直接这样用:worker.balancer.balance_workers=node2。
worker.node2.reference=worker.template,这是种类似继承的用法,把其他的worker的属性都配在worker.template中,
如:worker.template.type=ajp13 worker.template.socket_keepalive=true
worker.template.ping_mode=A
node2一旦调用:worker.node2.reference=worker.template,它就具有了上面的上属性。这样便于维护,修改。
上面的worker.node2.lbfactor =1 表示加载因子,如果两个节点都是1,则他们将按1:1获得请求量,你可以按需求修改。
你可以根据自己需求来添加和减少参与负载均衡的 tomcat实例个数。
三 tomcat集群
(前提 负载均衡已经成功)
集群其实就是在负载均衡的基础上实现同一session的复制,即当我在tomcatA上建立了session ,如果tomcatA突然故障或者因为负载均衡的原因,我发的第二次数据跳到了tomcatB上,这时候我还能用在tomcatA上建立的session id与之会话 而不是重先在tomcatB上建立新的session id 。
如果只是希望某个工程实现session复制,只需在该工程的web.xml文件中<web-app>节点中添加<distributable/>即可。
如果希望tomcat下所有的工程都实现session复制,则可以修改tomcat 安装目录下conf文件夹中的context.xml文件。将其中的<Context>改为<Context distributable=”true”>
JK+apache+tomcat(负载均衡、集群、more web per IP)综合例子
1环境
三台PC
PCA(ip:172.31.14.85 安装apache ,tomcat。 路径:apache:D:/Apache2.2 tomcat:D:/apache-tomcat-6.0.18))
PCB(ip:172.31.8.58 仅安装tomcat 路径tomcat:D:/apache-tomcat-6.0.18)
PCC(ip:172.31.10.168 只用于访问站点 )
(这些IP地址是我实验时的真实地址,你可以自行修改,但切记要保证网络畅通):
2 步骤
PCA上:
a. 把jk资源文件包里的workers.properties、httpd-jk.conf文件拷贝到D:/Apache2.2/conf文件夹中,并对worker.properties文件 node1和nodel2的部分属性进行修改:
worker.balancer.balance_workers=node1
worker.node1.reference=worker.template
worker.node1.host=localhost
worker.node1.port=8009
worker.balancer.balance_workers=node2
worker.node2.reference=worker.template
worker.node2.host=172.31.8.58
worker.node2.port=8009
worker.node2.lbfactor =1
b.把mod_jk-1.2.31-httpd-2.2.3.so文件放进D:/Apache2.2/manual文件夹,并改名为mod_jk.so。
c.打开D:/Apache2.2/conf 下的httpd.conf,去掉Include conf/extra/httpd-vhosts.conf 代码的注释(去掉#)。
d.打开D:/Apache2.2/conf/extra下的httpd-vhosts.conf文件,找到NameVirtualHost *:80代码,在其前一行添加代码:Include conf/httpd-jk.conf
e.继续 在httpd-vhosts.conf文件的末尾添加虚拟机,代码如下:
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.storm.com
DocumentRoot "C:/www/zcglxt"
ServerName www.zcglxt.com
ErrorLog "logs/dummy-host2.storm.com-error.log"
CustomLog "logs/dummy-host2.storm.com-access.log" common
# All requests go to worker1 by default
JkMount /* balancer
# Serve html, jpg and gif using httpd
JkUnMount /*.html balancer
JkUnMount /*.jpg balancer
JkUnMount /*.gif balancer
<Directory "C:/www/zcglxt">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.storm.com
DocumentRoot "C:/www/test"
ServerName www.test.com
ErrorLog "logs/dummy-www.test.com.log"
CustomLog "logs/dummy-www.test.com.log-access.log" common
# All requests go to worker1 by default
JkMount /* balancer
# Serve html, jpg and gif using httpd
JkUnMount /*.gif balancer
<Directory "C:/www/test" >
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
f.打开D:/apache-tomcat-6.0.18/conf中的server.xml文件,修改虚拟主机:()
<Host name="www.zcglxt.com" appBase="zcglxt"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="c:/www/zcglxt" debug="0" reloadbale="true"/>
</Host>
<Host name="www.test.com" appBase="test"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="c:/www/test" debug="0" reloadbale="true"/>
</Host>
(apache和tomcat中的虚拟主机目录要相同)
PCB上的配置:
在这台机子上只需配置tomcat的虚拟机。(同PCA 中第f步的配置完全一样)
PCC上的配置
这台电脑主要是用来访问站点,作测试用。用记事本打开本机C:/Windows/System32/drivers/etc下的hosts文件,在文中添加代码
172.31.14.85 www.test.com
172.31.14.85 www.zcglxt.com
写好两个web工程分别同时对应地放到apache和tomcat的虚拟机目录中。在pcc中打开IE 用www.test.comm 、 www.zcglxg.com 、www.test.comm:8080 、 www.zcglxg.com:8080访问站点,并观看PCA和PCB上的tomcat后台信息。
总结:
apache与tomcat通过 ajp协议通信,它通过 JkUnMount 和
JkMount 来决定那种类型的数据请求由自己处理,哪种需要tomcat来处理。如果不做负载均衡,只要把数据抛给ajp类型的worker,直接由worker自己来处理。如果需要做负载均衡,则apache需要把数据交给lb类型的worker,再由lb类型的worker将数据请求按平衡加载因子(lbfactor)比例分发给参与负载均衡的ajp类型的worker来处理。要实现集群,也就是要保证session能够共享,如果只想指定的web工程有需要session共享,则只需将该工程下的web.xml文件中添加<distributable/>即可,如果想tomcat下的所有工程都session共享,则可以只修改tomcat 的conf文件夹下的context.conf文件,将其中的<context>改为<context distributable=”true”>,而不需再去一一修改具体的工程。