您的位置:首页 > 运维架构 > Tomcat

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>


5 测试

启动tomcat1-4 再启动apache
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不接受新请求

总结完毕
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: