apache+tomcat+mod_jk做负载均衡
2010-04-14 17:25
411 查看
最近做一个网站项目,需要考虑tomcat负载均衡问题,以下是我的总结.
1
Tomcat6(4个)
Apache2.2
mod_jk-1.2.30-httpd-2.2.3.so
2
Apache是http服务器,负责接收http请求。如何将请求分发给后台tomcat 呢,这就需要mod_jk了,mod_jk是Apache用来链接tomcat的模块。它需要配置在Apache中。下面描述的是他们各自的分工情况
Apache要做的:Apache默认处理接收到的所有http请求,但可通过配置将请求转发给某个模块处理,并将模块处理结果返回,在这里我们将所有请求都转发给mod_jk去处理。
Mod_jk要做的:
a)
登记所有的tomcat服务器,并针对不同功能划分的tomcat做不同的配置。
b)
将从Apache接收到的请求按策略分配给tomcat。分配策略如下:
i.
对于新的会话按配置比例分发给tomcat
ii.
对于已有会话(http中包含session信息)的请求会发送给创建该会话的tomcat
iii.
当创建会话的tomcat无法响应时,发送给该tomcat指定的备份tomcat。如果没有指定,则视为新会话处
理。
Tomcat要做的:处理mod_jk发送过来的请求并返回结果。之前提到如果某一tomcat无法响应转由其他tomcat处理时,原有的session信息将会丢失。为解决此问题,于是就有了session同步的概念,即多个服务器之间共享session,当某一服务器不同提供服务时不会导致用户session丢失。Tomcat的session共享是基于ip组播协议实现的。(http://blog.csdn.net/wu_jietian/archive/2010/04/13/5480010.aspx
)这里只需要知道session同步是可以通过配置实现的,并且是由Tomcat实现的而非mod_jk。至于具体细节请参考另一篇文章(http://blog.csdn.net/wu_jietian/archive/2010/04/13/5479990.aspx
)
了解了原理之后,配置起来就水到渠成了。
3
代码必须符合以下几点要求:
1.session 中的 attribute必须继承java.io.Serializable
2.程序中如果存在全局变量,需要考虑多个Tomcat间变量同步的问题。
4
a) 安装tomcat、apache2.2 略。 网上资料大把,不再重复。
注意事项:apache需要设置最大并行连接数,不同的操作系统配置的方式不同,因为不同的系统使用的是不同的多路处理模块。配置视情况而定。
b)
安装并配置mod_jk
i. 安装mod_jk:
把下载的 mod_jk-1.2.28-httpd-2.2.3.so 改名为 mod_jk2.so 放到apache的modules目录下。
修改apache的conf目录下的httpd.conf,在文件最后加入一行include conf/mod_jk2.conf,在conf目录下创建mod_jk2.conf文件,内容如下:
#
加载
mod_jk Module
[b]LoadModule jk_module modules/mod_jk-1.2.30-httpd-2.2.3.so
[/b]
[b]#
指定
workers.properties
文件路径
[/b]
[b]JkWorkersFile conf/workers.properties
[/b]
[b]#
指定
log
目录
[/b]
[b]JkLogFile logs/mod_jk2.log
[/b]
[b]#
指定那些请求交给
tomcat
处理
,"controller"
为在
workers.propertise
里指定的负载分配控制器
[/b]
[b]JkMount /* controller
[/b]
ii.配置mod_jk:
worker.list =
controller,tomcat4,tomcat3,tomcat2,tomcat1
#server
列表
tomcat1-tomcat4
命名必须与
tomcat
配置文件
server.xml
中的
jvmRoute
相对应
#========tomcat1========
worker.tomcat1.port=8009
#ajp13
端口号,在
tomcat
下
server.xml
配置
,
默认
8009
worker.tomcat1.host=localhost
#tomcat
的主机地址,如不为本机,请填写
ip
地址
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor = 1
#server
的加权比重,值越高,分得的请求越多
worker.tomcat1.redirect = tomcat2
#
指定
tomcat1
无法提供服务后由
tomcat2
继续提供服务
#========tomcat2========
worker.tomcat2.port=8010
#ajp13
端口号,在
tomcat
下
server.xml
配置
,
默认
8009
worker.tomcat2.host=localhost
#tomcat
的主机地址,如不为本机,请填写
ip
地址
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor = 1
#server
的加权比重,值越高,分得的请求越多
worker.tomcat2.redirect = tomcat1
#
指定
tomcat2
无法提供服务后由
tomcat1
继续提供服务
worker.tomcat2.activation = d
#
指定
tomcat2
只接收属于它的
session
的请求,隐含意思是新的请求不会发给
tomcat2
。
#
如果
tomcat1
于
tomcat2
实现
session
共享且
tomcat1
挂掉时,
tomcat2
可以且只能为
session
属于
tomcat1
的请求提供服务。(可能比较绕,需要费几个脑细胞)
#========tomcat3========
worker.tomcat3.port=8011
#ajp13
端口号,在
tomcat
下
server.xml
配置
,
默认
8009
worker.tomcat3.host=localhost
#tomcat
的主机地址,如不为本机,请填写
ip
地址
worker.tomcat3.type=ajp13
worker.tomcat3.lbfactor = 1
#server
的加权比重,值越高,分得的请求越多
worker.tomcat3.redirect = tomcat4
#========tomcat4========
worker.tomcat4.port=8012
#ajp13
端口号,在
tomcat
下
server.xml
配置
,
默认
8009
worker.tomcat4.host=localhost
#tomcat
的主机地址,如不为本机,请填写
ip
地址
worker.tomcat4.type=ajp13
worker.tomcat4.lbfactor = 1
#server
的加权比重,值越高,分得的请求越多
worker.tomcat4.redirect = tomcat3
worker.tomcat4.activation = d
#========controller,
负载均衡控制器
========
worker.controller.type=lb
worker.controller.balanced_workers=tomcat4,tomcat3,tomcat2,tomcat1 #
指定分担请求的
tomcat
worker.controller.sticky_session=1
c) 配置tomcat
i.
<Server port="8005"
shutdown="SHUTDOWN">
如
果是同一台电脑,port不能重复
ii.
<Engine
name="Catalina" defaultHost="localhost">
改为<Engine name="Catalina"
defaultHost="localhost" jvmRoute="tomcat1-4">
iii. 设置session共享,Engine节点下插入以下配置:
<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="4000"
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>
Port需要特殊说明:address 和port都相同的tomcat视为一个集群,session共享是发生在集群内部的,因此这里我们 将tomcat1,2为一组及port=45564,tomcat3,4为一组port=45565。
iv. 在tomcat中添加应用testGroup,在其根目录下增加index.jsp文件,index.jsp内容如下
<%
session.setAttribute("session1","session1");
//tomcat2
的则改为
session.setAttribute("session2","session2");
以此类推
System.out.println("===========================");
System.out.println(session.getAttribute("session1"));
System.out.println(session.getAttribute("session2"));
System.out.println(session.getAttribute("session3"));
System.out.println(session.getAttribute("session4"));
System.out.println("sessionId = " + session.getId());
%>
<html>
<body >
<center>
<h1>Tomcat 1</h1>
<!--tomcat2
的则改为
Tomcat 2
以此类推
-->
</body>
</html>
v.在web.xml加入 <distributable/> 即可
<web-app
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"
version="2.5">
<distributable/>
<display-name>testGroup</display-name>
</web-app>
a)反复重启浏览器访问http://127.0.0.1/testGroup
你会发现只有tomcat1和tomcat3 接收到的请求。(注意tomcat控制台打印信息)
b) 访问http://127.0.0.1/testGroup
,比如当前页面显示是tomcat1,此时关闭tomcat1,刷新页面,页面应该显示为tomcat2.并且tomcat2后台打印信息应为
==========
session1
session2
null
null
你会发现tomcat1,2之间实现了session共享
c)之后反复重启浏览器访问,你会发现页面显示的都是tomcat3,因为tomcat1挂了,tomcat2,4不接受新请求
总结完毕
1
环境
Tomcat6(4个)Apache2.2
mod_jk-1.2.30-httpd-2.2.3.so
2
原理简述
Apache是http服务器,负责接收http请求。如何将请求分发给后台tomcat 呢,这就需要mod_jk了,mod_jk是Apache用来链接tomcat的模块。它需要配置在Apache中。下面描述的是他们各自的分工情况
Apache要做的:Apache默认处理接收到的所有http请求,但可通过配置将请求转发给某个模块处理,并将模块处理结果返回,在这里我们将所有请求都转发给mod_jk去处理。
Mod_jk要做的:
a)
登记所有的tomcat服务器,并针对不同功能划分的tomcat做不同的配置。
b)
将从Apache接收到的请求按策略分配给tomcat。分配策略如下:
i.
对于新的会话按配置比例分发给tomcat
ii.
对于已有会话(http中包含session信息)的请求会发送给创建该会话的tomcat
iii.
当创建会话的tomcat无法响应时,发送给该tomcat指定的备份tomcat。如果没有指定,则视为新会话处
理。
Tomcat要做的:处理mod_jk发送过来的请求并返回结果。之前提到如果某一tomcat无法响应转由其他tomcat处理时,原有的session信息将会丢失。为解决此问题,于是就有了session同步的概念,即多个服务器之间共享session,当某一服务器不同提供服务时不会导致用户session丢失。Tomcat的session共享是基于ip组播协议实现的。(http://blog.csdn.net/wu_jietian/archive/2010/04/13/5480010.aspx
)这里只需要知道session同步是可以通过配置实现的,并且是由Tomcat实现的而非mod_jk。至于具体细节请参考另一篇文章(http://blog.csdn.net/wu_jietian/archive/2010/04/13/5479990.aspx
)
了解了原理之后,配置起来就水到渠成了。
3
约束
代码必须符合以下几点要求:1.session 中的 attribute必须继承java.io.Serializable
2.程序中如果存在全局变量,需要考虑多个Tomcat间变量同步的问题。
4
部署
a) 安装tomcat、apache2.2 略。 网上资料大把,不再重复。注意事项:apache需要设置最大并行连接数,不同的操作系统配置的方式不同,因为不同的系统使用的是不同的多路处理模块。配置视情况而定。
b)
安装并配置mod_jk
i. 安装mod_jk:
把下载的 mod_jk-1.2.28-httpd-2.2.3.so 改名为 mod_jk2.so 放到apache的modules目录下。
修改apache的conf目录下的httpd.conf,在文件最后加入一行include conf/mod_jk2.conf,在conf目录下创建mod_jk2.conf文件,内容如下:
#
加载
mod_jk Module
[b]LoadModule jk_module modules/mod_jk-1.2.30-httpd-2.2.3.so
[/b]
[b]#
指定
workers.properties
文件路径
[/b]
[b]JkWorkersFile conf/workers.properties
[/b]
[b]#
指定
log
目录
[/b]
[b]JkLogFile logs/mod_jk2.log
[/b]
[b]#
指定那些请求交给
tomcat
处理
,"controller"
为在
workers.propertise
里指定的负载分配控制器
[/b]
[b]JkMount /* controller
[/b]
ii.配置mod_jk:
worker.list =
controller,tomcat4,tomcat3,tomcat2,tomcat1
#server
列表
tomcat1-tomcat4
命名必须与
tomcat
配置文件
server.xml
中的
jvmRoute
相对应
#========tomcat1========
worker.tomcat1.port=8009
#ajp13
端口号,在
tomcat
下
server.xml
配置
,
默认
8009
worker.tomcat1.host=localhost
#tomcat
的主机地址,如不为本机,请填写
ip
地址
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor = 1
#server
的加权比重,值越高,分得的请求越多
worker.tomcat1.redirect = tomcat2
#
指定
tomcat1
无法提供服务后由
tomcat2
继续提供服务
#========tomcat2========
worker.tomcat2.port=8010
#ajp13
端口号,在
tomcat
下
server.xml
配置
,
默认
8009
worker.tomcat2.host=localhost
#tomcat
的主机地址,如不为本机,请填写
ip
地址
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor = 1
#server
的加权比重,值越高,分得的请求越多
worker.tomcat2.redirect = tomcat1
#
指定
tomcat2
无法提供服务后由
tomcat1
继续提供服务
worker.tomcat2.activation = d
#
指定
tomcat2
只接收属于它的
session
的请求,隐含意思是新的请求不会发给
tomcat2
。
#
如果
tomcat1
于
tomcat2
实现
session
共享且
tomcat1
挂掉时,
tomcat2
可以且只能为
session
属于
tomcat1
的请求提供服务。(可能比较绕,需要费几个脑细胞)
#========tomcat3========
worker.tomcat3.port=8011
#ajp13
端口号,在
tomcat
下
server.xml
配置
,
默认
8009
worker.tomcat3.host=localhost
#tomcat
的主机地址,如不为本机,请填写
ip
地址
worker.tomcat3.type=ajp13
worker.tomcat3.lbfactor = 1
#server
的加权比重,值越高,分得的请求越多
worker.tomcat3.redirect = tomcat4
#========tomcat4========
worker.tomcat4.port=8012
#ajp13
端口号,在
tomcat
下
server.xml
配置
,
默认
8009
worker.tomcat4.host=localhost
#tomcat
的主机地址,如不为本机,请填写
ip
地址
worker.tomcat4.type=ajp13
worker.tomcat4.lbfactor = 1
#server
的加权比重,值越高,分得的请求越多
worker.tomcat4.redirect = tomcat3
worker.tomcat4.activation = d
#========controller,
负载均衡控制器
========
worker.controller.type=lb
worker.controller.balanced_workers=tomcat4,tomcat3,tomcat2,tomcat1 #
指定分担请求的
tomcat
worker.controller.sticky_session=1
c) 配置tomcat
i.
<Server port="8005"
shutdown="SHUTDOWN">
如
果是同一台电脑,port不能重复
ii.
<Engine
name="Catalina" defaultHost="localhost">
改为<Engine name="Catalina"
defaultHost="localhost" jvmRoute="tomcat1-4">
iii. 设置session共享,Engine节点下插入以下配置:
<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="4000"
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>
Port需要特殊说明:address 和port都相同的tomcat视为一个集群,session共享是发生在集群内部的,因此这里我们 将tomcat1,2为一组及port=45564,tomcat3,4为一组port=45565。
iv. 在tomcat中添加应用testGroup,在其根目录下增加index.jsp文件,index.jsp内容如下
<%
session.setAttribute("session1","session1");
//tomcat2
的则改为
session.setAttribute("session2","session2");
以此类推
System.out.println("===========================");
System.out.println(session.getAttribute("session1"));
System.out.println(session.getAttribute("session2"));
System.out.println(session.getAttribute("session3"));
System.out.println(session.getAttribute("session4"));
System.out.println("sessionId = " + session.getId());
%>
<html>
<body >
<center>
<h1>Tomcat 1</h1>
<!--tomcat2
的则改为
Tomcat 2
以此类推
-->
</body>
</html>
v.在web.xml加入 <distributable/> 即可
<web-app
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"
version="2.5">
<distributable/>
<display-name>testGroup</display-name>
</web-app>
5 测试
启动tomcat1-4 再启动apachea)反复重启浏览器访问http://127.0.0.1/testGroup
你会发现只有tomcat1和tomcat3 接收到的请求。(注意tomcat控制台打印信息)
b) 访问http://127.0.0.1/testGroup
,比如当前页面显示是tomcat1,此时关闭tomcat1,刷新页面,页面应该显示为tomcat2.并且tomcat2后台打印信息应为
==========
session1
session2
null
null
你会发现tomcat1,2之间实现了session共享
c)之后反复重启浏览器访问,你会发现页面显示的都是tomcat3,因为tomcat1挂了,tomcat2,4不接受新请求
总结完毕
相关文章推荐
- Linux(Ubuntu)下apache tomcat mod_jk实现负载均衡全过程
- Apache+Tomcat+mod_jk 配置负载均衡后乱码问题解决
- apache下jk_mod负载均衡的实现整合tomcat
- Apache + Tomcat + mod jk 来实现负载均衡
- Apache + Tomcat +mod_jk- win7与linux下实现负载均衡与集群-
- 使用Apache + mod_jk + tomcat来实现tomcat集群的负载均衡出现的无法加载mod_jk.conf文件的问题
- apache以mod_jk方式实现tomcat的负载均衡集群
- Apache+Tomcat实现负载均衡及集群(session同步)--四、负载均衡(1)使用mod_jk
- Apache+Tomcat+mod_jk实现负载均衡
- Apache + Tomcat +mod_jk- win7与linux下实现负载均衡与集群-
- 【Apache+tomcat+mod_jk 实现负载均衡】
- Apache使用mod_jk/mod_proxy模块实现代理、负载均衡的配置
- Linux下Apache+Tomcat+JK实现负载均衡和群集的完整过程
- APACHE 2.2.8+TOMCAT6.0.14配置负载均衡 (apache集成mod_jk.so)
- 通过Apache+mod_JK+Tomcat集群实现负载均衡
- Apache+Tomcat实现负载均衡及集群(session同步)--四、负载均衡(2)使用mod_proxy
- 基于mod_proxy+Apache 2.2.16+Tomcat 7的负载均衡与集群配置
- JBoss4.2.3GA+Apache/2.2.11+mod_jk1.2.28 搭建负载均衡 全过程记录(附上搭建环境)
- Linux中Apache+Tomcat+JK实现负载均衡和群集的完整过程
- Linux中Apache+Tomcat+JK实现负载均衡和群集的完整过程(转载)