Apache+Tomcat实现集群及多应用对应多域名

来源:互联网 发布:深圳税友软件 编辑:程序博客网 时间:2024/06/05 06:41

最近工作上需要实现一个服务器上的tomcat的各个应用对应各自独立的域名,并且要实现多个tomcat的集群及负载均衡。上网看了很多文章,终于成功了,整理思路及步骤如下:

1.下载Apache,windows版本去http://www.apachelounge.com/download/ 找到最新的版本,32位和64位都有。另外http://httpd.apache.org/download.cgi也可以链接过去

2.下载tomcat,http://tomcat.apache.org/

3.直接解压就安装好了.

4.配置Apache,参考http://developer.51cto.com/art/201102/246338_all.htm ,http://www.blogjava.net/greatyuqing/archive/2013/02/13/395308.html

4.1在Apache安装目录下找到conf/httpd.conf文件,以文本编辑器打开。

把所有c:/Apache24,替换成解压所在路径,注意这里的路径中必须使用斜杠“/”;

修改 Listen 80 和 ServerName localhost:80  的端口,如果已经装了IIS,80端口会冲突的.

在Dos命令窗口进入相应的/Apache/bin 目录.

执行 httpd -k install 这样就把apache加入了系统服务 , 启动服务的命令为httpd.exe -k start

如果执行命令是出现 丢失MSVCR100.dll 的错误,可参考 http://wenda.haosou.com/q/1359642384060601 ,安装Microsoft Visual C++ 2010 Redistributable Package即可

此时访问http://localhost 可以看到 It works表示Apache能用了


然后配置Apache的集群及负载均衡
编辑conf/httpd.conf文件,去掉以下文本前的注释符(#)以便让Apache在启动时自动加载代理(proxy)模块。

LoadModule proxy_module modules/mod_proxy.so  LoadModule proxy_ajp_module modules/mod_proxy_ajp.so  LoadModule proxy_balancer_module modules/mod_proxy_balancer.so  LoadModule proxy_connect_module modules/mod_proxy_connect.so  LoadModule proxy_ftp_module modules/mod_proxy_ftp.so  LoadModule proxy_http_module modules/mod_proxy_http.so

4.2向下拉动文档找到节点,在DirectoryIndex index.html后加上index.jsp,这一步只是为了待会配置完tomcat后能看到小猫首页,可以不做。

## DirectoryIndex: sets the file that Apache will serve if a directory# is requested.#<IfModule dir_module>    DirectoryIndex index.html index.jsp</IfModule>


4.3继续下拉文档找到Include conf/extra/httpd-vhosts.conf,去掉前面的注释符。

# Virtual hostsInclude conf/extra/httpd-vhosts.conf


4.4用文本编辑器打开conf/extra/httpd-vhosts.conf,配置虚拟站点,在最下面加上。其中ServerName和ServerAdmin分别对应服务器和管理员邮箱

把原来默认的virtualhost节点注释掉,否则可能会报错

<VirtualHost *:80>    ServerAdmin admin@admin.com    ServerName 192.168.1.105    ServerAlias localhost    ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On    ProxyPassReverse / balancer://cluster/    ErrorLog "logs/lbtest-error.log"    CustomLog "logs/lbtest-access.log" common</VirtualHost>


这里balancer://是告诉Apache需要进行负载均衡的代理,后面的cluster是集群名,可以随意取,两个日志引擎ErrorLog负责记录错误,CustomLog负责记录所有的http访问以及返回状态,日志名可以自己取,笔者取为lbtest

4.5httpd-vhosts.conf配置完毕,回到httpd.conf,在文档最下面加上

ProxyRequests Off        <proxy balancer://cluster>             BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1           BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2      </proxy> 


ProxyRequests Off 是告诉Apache需要使用反向代理(利用Apache进行负载均衡必须使用反向代理,关于更多负载均衡和反向代理详情可以参阅另一篇博客http://zyycaesar.javaeye.com/admin/blogs/293839), 用于配置工作在tomcat集群中的所有节点,这里的"cluster"必须与上面的集群名保持一致。Apache通过ajp协议与tomcat进行通信,ip地址和端口唯一确定了tomcat节点和配置的ajp接受端口。loadfactor是负载因子,Apache会按负载因子的比例向后端tomcat节点转发请求,负载因子越大,对应的tomcat服务器就会处理越多的请求,如两个tomcat都是1,Apache就按1:1的比例转发,如果是2和1就按2:1的比例转发。route参数对应后续tomcat配置中的引擎路径(jvmRoute)。


4.6重启Apache服务,如果此时访问http://localhost/将会返回503错误,打开刚才配置的错误日志logs/lbtest-error.log,可以看到错误原因是因为后台服务器没有响应,因为此时tomcat尚未配置和启动。

可以用httpd -k stop来确认服务是否起来了,然后在/logs/error.log里查看错误,

a.如果看到错误,Unclean shutdown of previous Apache run,可以通过删除/logs/httpd.pid来解决 参考http://www.cnblogs.com/noblepaul/archive/2004/10/05/49033.html

b.如果看到错误 Failed to lookup provider 'shm' for 'slotmem': is mod_slotmem_shm loaded??,通过修改httpd.conf文件,取消注释#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so 来解决

c.如果看到错误Cannot find LB Method: byrequests, 通过修改httpd.conf文件,取消注释 #LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so 来解决,参考 http://www.111cn.net/phper/apache/51776.htm



5.配置tomcat

5.1配置关闭端口,找到,t1不变,把t2改为9005。

<Server port="8005" shutdown="SHUTDOWN">

5.2 配置Connector的端口,找到non-SSL HTTP/1.1 Connector,即tomcat单独工作时的默认Connector,保留t1默认配置,在8080端口侦听,而把t2设置为在9080端口侦听。

<Connector port="8100" protocol="HTTP/1.1"               connectionTimeout="20000"               redirectPort="8443" />


5.3找到AJP 1.3 Connector,,这是tomcat接收从Apache过来的ajp连接请求时使用的端口,保留t1默认设置,把t2端口改为9009。注意,这里的端口对应Apache httpd.conf中BalancerMember中配置的ajp连接端口。

<!-- Define an AJP 1.3 Connector on port 8009 -->    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />


5.4配置引擎,找到,去掉这段或改为注释,把上方紧挨的注释符去掉,对于t2,去掉注释符并把jvm1改为jvm2。这里的jvmRoute对应Apache httpd.conf中BalancerMember中配置的route参数。

<!-- You should set jvmRoute to support load-balancing via AJP ie :-->    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">       <!-- <Engine name="Catalina" defaultHost="localhost">-->


5.5 打开注释,这里的配置是为了可以在集群中的所有tomcat节点间共享会话(Session)。如果仅仅为了获得一个可用的tomcat集群,Cluster只需要这么配置就可以了,对于更多的Cluster配置笔者将另文解释。

 <!--For clustering, please take a look at documentation at:          /docs/cluster-howto.html  (simple how to)          /docs/config/cluster.html (reference documentation) -->            <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>


5.6 server.xml的配置修改完毕,下一步需要对具体的应用进行配置。在webapps目录下新建test目录,在test目录下新建test.jsp文件,代码如下:

<%@ page contentType="text/html; charset=GBK" %> <%@ page import="java.util.*" %> <html><head><title>Cluster App Test</title></head> <body> Server Info:  <%  out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%> <%    out.println("<br> ID " + session.getId()+"<br>");     String dataName = request.getParameter("dataName");        if (dataName != null && dataName.length() > 0) {       String dataValue = request.getParameter("dataValue");       session.setAttribute(dataName, dataValue);    }          out.print("<b>Session 列表</b>");          Enumeration e = session.getAttributeNames();        while (e.hasMoreElements()) {       String name = (String)e.nextElement();       String value = session.getAttribute(name).toString();       out.println( name + " = " + value+"<br>");           System.out.println( name + " = " + value);     }  %>   <form action="test.jsp" method="POST">     名称:<input type=text size=20 name="dataName">      <br>     值:<input type=text size=20 name="dataValue">      <br>     <input type=submit>    </form> </body> </html> 


5.7 在test目录下继续新建WEB-INF目录,再WEB-INF下新建web.xml,在节点下加入,web.xml的最后一行含有: <distributable/>,这一步非常重要,是为了通知tomcat服务器,当前应用需要在集群中的所有节点间实现Session共享。如果tomcat中的所有应用都需要Session共享,也可以把conf/context.xml中的改为,这样就不需对所有应用的web.xml再进行单独配置。

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><distributable/></web-app>

启动t1,待t1启动完成后再启动t2。再次访问http://localhost,可以看到小猫页面。访问http://localhost/test/test.jsp。可以看到包括服务器地址,端口,sessionid等信息在内的页面。

注意这里的sessionid,与平常的sessionid相比多了小数点和后面的部分,这里的jvm1即处理当前请求tomcat服务器的jvmRoute,通过这里可以知道是集群中的哪一个服务器处理了当前请求。在文本框中输入名称和值,点击按钮,信息就保存到了Session中,并且显示到页面上。不断点击按钮,可以发现输入的信息并未丢失,而且sessionid小数点之前的部分保持不变,而小数点后面的字符不停的变化,表明是由不同的tomcat服务器处理了这些请求。这样就实现了负载均衡,并且集群中的不同节点间可以实现会话的共享。此时如果停止一个tomcat服务器t2,Apache将会自动把后续请求转发到集群中的其他服务器即t1。重启t2后,Apache会自动侦测到t2的状态为可用,然后会继续在t1和t2间进行负载均衡。

如果需要向集群中增加节点,首先需要对tomcat作类似配置,然后修改Apache httpd.conf,增加BalancerMember,指向新增的tomcat即可。


另外参考http://developer.51cto.com/art/201105/260375.htm ,配置分应用共享session

<!--<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>-->  <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">        <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"/>        </Channel>    </Cluster> 

6.配置不同应用对应不同域名 参考http://blog.csdn.net/chenhui1219/article/details/6046925

编辑tomcat的 server.xml,修改host节点

<Host name="localhost" debug="0" appBase="D:/Tomcat 5.0/webapps"unpackWARs="true" autoDeploy="true"xmlValidation="false" xmlNamespaceAware="false"><Alias>localhost.com</Alias><Logger className="org.apache.catalina.logger.FileLogger"directory="logs" prefix="localhost_log." suffix=".txt"timestamp="true"/><Context path="" docBase="D:/Tomcat 5.0/webapps/gg" reloadable="true" caseSensitive="false" debug="0"></Context></Host><Host name="one.localhost" debug="0" appBase="D:/Tomcat 5.0/webapps"unpackWARs="true" autoDeploy="true"xmlValidation="false" xmlNamespaceAware="false"><Alias>one.localhost.com</Alias><Logger className="org.apache.catalina.logger.FileLogger"directory="logs" prefix="localhost_log." suffix=".txt"timestamp="true"/><Context path="" docBase="D:/Tomcat 5.0/webapps/kk/a" reloadable="true" caseSensitive="false" debug="0"></Context></Host><Host name="two.localhost" debug="0" appBase="D:/Tomcat 5.0/webapps"unpackWARs="true" autoDeploy="true"xmlValidation="false" xmlNamespaceAware="false"><Alias>two.localhost.com</Alias><Logger className="org.apache.catalina.logger.FileLogger"directory="logs" prefix="localhost_log." suffix=".txt"timestamp="true"/><Context path="" docBase="D:/Tomcat 5.0/webapps/kk/b" reloadable="true" caseSensitive="false" debug="0"></Context></Host>

docBase存的是工程路径,如果是在webapps下,直接写 /目录名 就好了.

修改<Engine name="Catalina" defaultHost="localhost"> ,里面的defaultHost需是定义的其中一个hostname






0 0