一、资源以及环境
1)、Win7
2)、Apache2.4(x64)
3)、tomcat7.0.73
4)、jdk1.7.0_60(x64)
具体链接:https://download.youkuaiyun.com/download/jianbao/12162967
二、Apache的安装以及配置
笔者的Apache安装在D:\apache\Apache2.4,具体的安装直接Next(填写Server,邮箱的地方以默认为准),笔者的端口为80。安装完之后,在浏览器中输入http://localhost
网页上会打出It Works,即Apache安装成功。
如下图所示:
三、Apache负载的实现方式
先说明一下,两种配置的入口都是httpd.conf,在这个文件中分别引入mod_jk.conf或者mod_proxy.conf
1、mod_proxy
1)、打开httpd.conf配置
在\conf\httpd.conf文件中,需要打开以下几个.so模块的配置
LoadModule headers_module modules/mod_headers.so
#与以下负载方式mod_proxy.conf有关,对应于ProxySet lbmethod=bybusyness
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
#与以下负载方式mod_proxy.conf有关,对应于ProxySet lbmethod=byrequests
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
#与以下负载方式mod_proxy.conf有关,对应于ProxySet lbmethod=bytraffic
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
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
#此处不打开,在apache使用mod_proxy方式的时候,apache启动报错
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
2)、配置代理规则
在httpd.conf最底部增加引用文件配置Include conf/mod_proxy.conf,然后在\conf下新增mod_proxy.conf
mod_proxy.conf的具体内容如下:
<VirtualHost *:80> #80是Apache Server的端口
ServerAdmin [email]admin@www.tendawifi.com[/email]
ServerName 127.0.0.1
ServerAlias 127.0.0.1
ProxyPreserveHost on
ProxyPass / balancer://127.0.0.1/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse / balancer://127.0.0.1/
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
ProxyErrorOverride On
ErrorLog "logs/error.log"
CustomLog "logs/access.log" common
</VirtualHost>
ProxyRequests Off
<proxy balancer://127.0.0.1>
BalancerMember ajp://127.0.0.1:8019 loadfactor=1 route=tomcat1 #8019为第一个tomcat的ajp端口,tomcat1为第一个tomcat的jvmRoute值
BalancerMember ajp://127.0.0.1:8029 loadfactor=1 route=tomcat2 #8029为第二个tomcat的ajp端口,tomcat2为第二个tomcat的jvmRoute值
# status=+H为配置热备,当所有机器都over时,才会请求该机器
#BalancerMember http://127.0.0.1:8009 status=+H
#按照请求次数均衡(默认)
#ProxySet lbmethod=byrequests
#按照权重
#ProxySet lbmethod=bytraffic
#按负载量,也就是往负载少的派发新请求
#ProxySet lbmethod=bybusyness
ProxySet lbmethod=byrequests #与三、1、1)中打开的.so模块配对
</proxy>
<VirtualHost *:80> #80是Apache Server的端口
ServerAdmin [email]admin@www.tendawifi.com[/email]
ServerName 127.0.0.1
ServerAlias 127.0.0.1
ProxyPreserveHost on
ProxyPass / balancer://127.0.0.1/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse / balancer://127.0.0.1/
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
ProxyErrorOverride On
ErrorLog "logs/error.log"
CustomLog "logs/access.log" common
</VirtualHost>
ProxyRequests Off
<proxy balancer://127.0.0.1>
BalancerMember ajp://127.0.0.1:8019 loadfactor=1 route=tomcat1 #8019为第一个tomcat的ajp端口,tomcat1为第一个tomcat的jvmRoute值
BalancerMember ajp://127.0.0.1:8029 loadfactor=1 route=tomcat2 #8029为第二个tomcat的ajp端口,tomcat2为第二个tomcat的jvmRoute值
# status=+H为配置热备,当所有机器都over时,才会请求该机器
#BalancerMember http://127.0.0.1:8009 status=+H
#按照请求次数均衡(默认)
#ProxySet lbmethod=byrequests
#按照权重
#ProxySet lbmethod=bytraffic
#按负载量,也就是往负载少的派发新请求
#ProxySet lbmethod=bybusyness
ProxySet lbmethod=byrequests #与三、1、1)中打开的.so模块配对
</proxy>
2、mod_jk
1)、注销mod_proxy配置,即在httpd.conf文件最底部注销#Include conf/mod_proxy.conf
在httpd.conf最底部增加引用文件配置Include conf/mod_jk.conf(注销mod_proxy配置,两者是二选一),然后在\conf下新增mod_jk.conf以及workers.properties
2)、mod_jk.conf
#加载mod_jk Module mod_jk.so 软件的名字根据实际定
LoadModule jk_module modules/mod_jk.so
#指定workers.properties文件路径
JkWorkersFile conf/workers.properties
#指定jk的日志输出文件
JkLogFile logs/mod_jk.log
#指定日志级别
JkLogLevel warn
#指定那些请求交给tomcat处理,"controller"为在workers.propertise里指定的负载分配控制器名
JkMount /* controller
#加载mod_jk Module mod_jk.so 软件的名字根据实际定
LoadModule jk_module modules/mod_jk.so
#指定workers.properties文件路径
JkWorkersFile conf/workers.properties
#指定jk的日志输出文件
JkLogFile logs/mod_jk.log
#指定日志级别
JkLogLevel warn
#指定那些请求交给tomcat处理,"controller"为在workers.propertise里指定的负载分配控制器名
JkMount /* controller
3)、workers.properties
#server
worker.list = controller
#========tomcat1========
worker.tomcat1.port=8019 #8019是第一个tomcat的ajp端口
worker.tomcat1.host=127.0.0.1
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=1
#========tomcat3========
worker.tomcat2.port=8029 #8029是第二个tomcat的ajp端口
worker.tomcat2.host=127.0.0.1
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=1
#========controller,负载均衡控制器========
#负载均衡控制器类型,lbfactor是负载平衡因数(Load Balance Factor)
worker.controller.type=lb
#指定分担请求的tomcat列表
worker.controller.balance_workers=tomcat1,tomcat2
worker.controller.sticky_session=false
#设置用于负载均衡的server的session可否共享
worker.controller.sticky_session_force=1
4)、把mod_jk.so拷贝到\modules\下
四、tomcat的配置
拷贝两个tomcat。
如果多个tomcat在不同的服务器上,即为水平分布;多个tomcat在同一台服务器上,即为垂直分布。
主要修改\conf\server.xml以及工程包所在的WEB-INF\web.xml。笔者把两个tomcat按照先后顺序写在一起
1、server.xml
修改点:
1)、关闭tomcat的端口
<Server port="8015" shutdown="SHUTDOWN">
*************************************************************
<Server port="8025" shutdown="SHUTDOWN">
2)、tomcat的http访问端口
<Connector port="8018" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
**************************************************************
<Connector port="8028" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
3)、tomcat的ajp端口,即与apache通信的端口,8019、8029是与负载配置文件对应的
<Connector port="8019" protocol="AJP/1.3" redirectPort="8443"/>
******************************************************************************
<Connector port="8029" protocol="AJP/1.3" redirectPort="8443"/>
4)、为Engine配置jvmRoute值,tomcat1、tomcat2是与负载配置对应的
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
*******************************************************************************
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
5)、打开Cluster集群配置,这个配置在两个tomcat中一致
<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"
mcastBindAddress="127.0.0.1"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="127.0.0.1"
tcpListenAddress="127.0.0.1"
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>
6)、在工程所在的路径下,配置WEB-INF\web.xml。笔者在这个地方掉入很大的一个坑,花了2天时间才研究明白。
例如:tomcat默认的web.xml在tomcat\webapps\ROOT\WEB-INF下,但是笔者的测试工程在tomcat\webapps\fzjh下。应该在tomcat\webapps\fzjh\下新建WEB-INF文件夹,并把web.xml拷贝到WEB-INF下。
在web.xml的标签</web-app>之前新增<distributable/>。两个tomcat都是这样。
7)、在tomcat\webapps\fzjh\新增sessionTest.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ 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>");
// 如果有新的 Session 属性设置
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0)
{
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.println("<b>Session 列表</b><br>");
System.out.println("============================");
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="sessionTest.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>
五、分别启动apache、tomcat1、tomcat2.在浏览器上进行测试。sessionId不变,但是访问的服务器在变化。另外,session值没有丢失,说明负载以及session共享成功。