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

apache+tomcat集群的负载均衡配置方式

2015-11-07 00:19 696 查看
有些时候我们需要使用多个tomcat来独立各个应用,而且又要使用80端口,这时候用apache+多个tomcat的方式是一种比较好的选择。

除此之外,我们采用这种方式有什么好处呢?1.提升静态文件的处理性能;2.利用web容器做负载均衡,容错处理;3.无缝的升级应用

环境

apache:httpd-2.2.17-win32-x86-openssl-0.9.8o.zip http://www.skycn.com/soft/1218.html
tomcat6.0

mod_jk-1.2.31-httpd-2.2.3.so http://tomcat.apache.org/connectors-doc/
1.apache配置

1.1安装mod_jk

将mod_jk-1.2.31-httpd-2.2.3.so复制到modules目录下,接着修改conf/httpd.conf,增加如下内容

# (httpd.conf)

# 加载 mod_jk 模块

LoadModule jk_module modules/mod_jk-1.2.31-httpd-2.2.3.so

#

# Configure mod_jk

#

JkWorkersFile conf/workers.properties

JkMountFile conf/uriworkermap.properties

JkLogFile logs/mod_jk.log

JkLogLevel warn

NameVirtualHost *:80

这里我们也可以看到,我们还需要在conf下建立2个文件workers.properties和uriworkermap.properties

workers.properties文件描述分发到tomcat的一些信息,以及如何分发信息

#

# workers.properties

#

# list the workers by name

worker.list=tomcatA,tomcatB

# localhost server 1

# ------------------------

worker.tomcatA.port=8009

worker.tomcatA.host=localhost

worker.tomcatA.type=ajp13

# localhost server 2

# ------------------------

worker.tomcatB.port=8029

worker.tomcatB.host=pc917

worker.tomcatB.type=ajp13

uriworkermap.properties

#URI 映射文件,用来指定哪些 URL 由 Tomcat 处理,你也可以直接在 httpd.conf 中配置这些 URI,但是独立这些配置的好处是jk模块会定期更新该文件的内

#容,使得我们修改配置的时候无需重新启动 Apache 服务器。

#

# uriworkermap.properties

#

/*=DLOG4J

/jkstatus=status

!/*.gif=DLOG4J

!/*.jpg=DLOG4J

!/*.png=DLOG4J

!/*.css=DLOG4J

!/*.js=DLOG4J

!/*.htm=DLOG4J

!/*.html=DLOG4J

2.tomcat配置

修改tomcatA的server.xml中的ajp端口为8009

<!-- Define an AJP 1.3 Connector on port 8009 -->

<Connector URIEncoding="UTF-8" port="8009" protocol="AJP/1.3" redirectPort="8443" />

修改tomcatA的server.xml中的ajp端口为8029

<Connector URIEncoding="UTF-8" port="8029" protocol="AJP/1.3" redirectPort="8444" />

3.增加虚拟目录,修改httpd.conf,增加如下内容,接着就可以通过相应的域名访问对应的tomcat了

<VirtualHost localhost>

ServerName localhost

#路径中不能存在空格

DocumentRoot C:/apache-tomcat-6.0.29/webapps

Serveralias localhost

Serveralias localhost

ErrorLog logs/shsc-error_log.txt

CustomLog logs/shsc-access_log.txt common

<Directory />

Options Indexes FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

</Directory>

#让Apache支持对servlet传送,用以Tomcat解析

JkMount /servlet/* tomcatA

#让Apache支持对jsp传送,用以Tomcat解析

JkMount /*.jsp tomcatA

#让Apache支持对.do传送,用以Tomcat解析

JkMount /*.do tomcatA

JkMount /*.html tomcatA

JkMount /* tomcatA

</VirtualHost>

<VirtualHost pc917>

ServerName pc917

#路径中不能存在空格

DocumentRoot C:/apache-tomcat-6.0.29_1/webapps

Serveralias pc917

Serveralias pc917

ErrorLog logs/shsc-error_log.txt

CustomLog logs/shsc-access_log.txt common

<Directory />

Options Indexes FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

</Directory>

#让Apache支持对servlet传送,用以Tomcat解析

JkMount /servlet/* tomcatB

#让Apache支持对jsp传送,用以Tomcat解析

JkMount /*.jsp tomcatB

#让Apache支持对.do传送,用以Tomcat解析

JkMount /*.do tomcatB

JkMount /*.html tomcatB

JkMount /* tomcatB

</VirtualHost>

4.最后建议将tomcat的HTTP1.1连接器屏蔽了,只允许用户通过apache转发需要的路径到tomcat,如果其他用户如果直接访问tomcat容器,这样的配置也就没有什么意义的,当然你也可以选择不关掉

不过这种方式只是通过不同域名访问到了不同的tomcat,适合一般虚拟主机之类的,一台机子部署N个相互不影响的tomcat,但是我们如果需要配置一个tomcat集群,使得用户请求均衡分发到各个tomcat,充分利用系统资源,下面将描述如何配置一个tomcat集群的负载均衡配置

5.tomcat集群

5.1修改workers.properties文件

#server

worker.list = controller

#========tomcat1========

worker.tomcatA.port=8009

worker.tomcatA.host=192.168.0.1

worker.tomcatA.type=ajp13

worker.tomcatA.lbfactor = 10 #负载权重

#========tomcat2========

worker.tomcatB.port=8029

worker.tomcatB.host=192.168.0.2

worker.tomcatB.type=ajp13

worker.tomcatB.lbfactor = 8 #负载权重

#========controller,负载均衡控制器========

worker.controller.type=lb

worker.controller.balanced_workers=tomcatA,tomcatB

worker.controller.sticky_session=1

这样就可以配置好2台tomcat集群,以权重10:8的方式分发请求(权重可以根据每台服务器的情况来配置),也可以在一台服务器内配置多个tomcat成为集群,使劲的用完服务器资源。

5.2 修改各个tomcat的server.xml配置

将tomcatA和tomcatB各自的<Engine name=-"Catalina" defaultHost="localhost">修改为如下内容(jvmRoute是唯一的)

tomcatA:

<!--You should set jvmRoute to support load-balancing via AJP-->

<Engine name="Standalone" defaultHost="localhost" jvmRoute="tomcatA">

tomcatB:

<!--You should set jvmRoute to support load-balancing via AJP-->

<Engine name="Standalone" defaultHost="localhost" jvmRoute="tomcatB">

为每个tomcat加上Cluster节点

<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"

managerClassName="org.apache.catalina.cluster.session.DeltaManager"

expireSessionsOnShutdown="false"

useDirtyFlag="true"

notifyListenersOnReplication="true">

......

</Cluster>

5.3 为每个部署到tomcat容器下的应用修改WEB-INF/web.xml,添加如下内容

<distributable/>

至今tomcat集群配置完成,可以测试下效果了,启动apache->启动tomcatA->启动tomcatB->关闭tomcatA->关闭tomcatB,观察各个阶段的效果

在普通的Web应用程序中如下代码片段即可完成Session中属性的变更

view plaincopy to clipboardprint?

Object o = request.getSession(true).getAttribute(LOGIN_USER_INFO_KEY);

UserInfo ui = (UserInfo) o;

ui.setAccessPageCount(ui.getAccessPageCount() + 1);

Object o = request.getSession(true).getAttribute(LOGIN_USER_INFO_KEY);

UserInfo ui = (UserInfo) o;

ui.setAccessPageCount(ui.getAccessPageCount() + 1);

但是在集群部署环境下该处理是不能完成Session复制的,必须用如下代码片段才可以

view plaincopy to clipboardprint?

Object o = request.getSession(true).getAttribute(LOGIN_USER_INFO_KEY);

UserInfo ui = (UserInfo) o;

ui.setAccessPageCount(ui.getAccessPageCount() + 1);

request.getSession().setAttribute(LOGIN_USER_INFO_KEY, ui);

AJP协议(http://yefeng.javaeye.com/blog/225171)

AJP13是定向包协议。因为性能原因,使用二进制格式来传输可读性文本。WEB服务器通过TCP连接和SERVLET容器连接。为了减少进程生成socket的花费,WEB服务器和SERVLET容器之间尝试保持持久性的TCP连接,对多个请求/回复循环重用一个连接。一旦连接分配给一个特定的请求,在请求处理循环结束之前不会在分配。换句话说,在连接上,请求不是多元的。这个是连接两端的编码变得容易,虽然这导致在一时刻会有很多连接。

一旦WEB服务器打开了一个到SERVLET容器的连接,连接处于下面的状态:

◆ 空闲

这个连接上没有处理的请求。

◆ 已分派

连接正在处理特定的请求。

一旦一个连接被分配给一个特定的请求,在连接上发送的基本请求信息是高度压缩的。在这点,SERVLET容器大概准备开始处理请求,当它处理的时候,它能发回下面的信息给WEB服务器:

◆ SEND_HEADERS

发送一组头到浏览器。

◆ SEND_BODY_CHUNK

发送一块主体数据到浏览器。

◆ GET_BODY_CHUNK

从请求获得下一个数据如果还没有全部传输完,如果请求内容的包长度非常大或者长度不确定,这是非常必要的。例如上载文件。注意这和HTTP的块传输没有关联。

◆ END_RESPONSE

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