用jk整合Apache和tomcat实现负载均衡

最近刚看完一些关于如何用jk整合Apache和tomcat的资料,为了防止自己忘记,把它们在这里都写下来。部分内容摘抄于网络。

首先下载tomcat, apache和jk。

1.  下载Apache HTTP server(2.2), 安装于“C:\Program Files\Apache Software Foundation\Apache2.2”

2. 下载mod_jk, 放在“Apache Software Foundation\Apache2.2\modules and rename it to mod_jk.so”

JK 是通过 AJP 协议与 Tomcat 服务器进行通讯的,Tomcat 默认的 AJP Connector 的端口是 8009。

<tomcat>/conf/server.xml:

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

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

JK 本身提供了一个监控以及管理的页面 jkstatus,通过 jkstatus 可以监控 JK 目前的工作状态以及对到 tomcat 的连接进行设置,如下图所示:

  1:监控以及管理的页面 jkstatus

 

在这个图中我们可以看到当前JK配了两个连接分别到 8109 和 8209 端口上,目前 s2 这个连接是停止状态,而 s1 这个连接自上次重启后已经处理了 47 万多个请求,流量达到 6.2 个 G,最大的并发数有 13 等等。我们也可以利用 jkstatus 的管理功能来切换 JK 到不同的 Tomcat 上,例如将 s2 启用,并停用 s1,这个在更新应用程序的时候非常有用,而且整个切换过程对用户来说是透明的,也就达到了无缝升级的目的。关于 JK 的配置文章网上已经非常多了,这里我们不再详细的介绍整个配置过程,但我要讲一下配置的思路,只要明白了配置的思路,JK 就是一个非常灵活的组件。

JK 的配置最关键的有三个文件,分别是

httpd.conf
Apache 服务器的配置文件,用来加载 JK 模块以及指定 JK 配置文件信息

workers.properties
到 Tomcat 服务器的连接定义文件

uriworkermap.properties
URI 映射文件,用来指定哪些 URL 由 Tomcat 处理,你也可以直接在 httpd.conf 中配置这些 URI,通过JkMount,比如:

JkMount /*.do route1

JkUnMount /output/*  loadbalancer (如果有不想转发目录,则用JkUnMount)

 #关掉主机Lookup,如果为on,很影响性能,可以有10多秒钟的延迟。

HostnameLookups Off

 

但是独立这些配置的好处是 JK 模块会定期更新该文件的内容,使得我们修改配置的时候无需重新启动 Apache 服务器。

其中第二、三个配置文件名都可以自定义。下面是一个典型的 httpd.conf 对 JK 的配置

Apache Software Foundation/Apache2.2/conf/httpd.conf

# (httpd.conf)

# 加载 mod_jk 模块

LoadModule jk_module modules/mod_jk.so

 

#

# Configure mod_jk

#

 

JkWorkersFile conf/workers.properties

JkMountFile conf/uriworkermap.properties

JkLogFile logs/mod_jk.log

JkLogLevel warn
 


 

接下来我们在 Apache 的 conf 目录下新建两个文件分别是 workers.properties、uriworkermap.properties。这两个文件的内容大概如下

#

# workers.properties

#

 

# list the workers by name

 

worker.list= route1, status

 

# localhost server 1

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

worker.s1.port=8009       #ajp13 端口号,在tomcat下server.xml配置,默认8009

worker.s1.host=localhost  #tomcat的主机地址,如不为本机,请填写ip地址

worker.s1.type=ajp13

worker.s1.lbfactor=1       #server的加权比重,值越高,分得的请求越多

 

# localhost server 2

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

worker.s2.port=8109

worker.s2.host=localhost

worker.s2.type=ajp13

worker.s2.lbfactor=1

worker.s2.stopped=1

 

worker. route1.type=lb

worker.retries=3

worker.route1.balanced_workers=s1, s2

worker.route1.sticky_session=1

 

worker.status.type=status
 
 

具体的参数含义如下:

A、worker.list=route1, status

  设定工作的负载平衡器,各Tomcat节点不能加入此列表。

B、worker. s1.lbfactor=1

  负载平衡的权重比,如果此权重比越大,则分配到此节点的请求越多,如以上两个节点的权重比为1:1,则为平均分配。


C、worker.route1.balanced_workers=s1, s2

  指定此负载平衡器负责的Tomcat应用节点。

D、worker.loadbalancer.sticky_session=true

   此处指定集群是否需要会话复制,如果设为true(或1),则表明为会话粘性,不进行会话复制,当某用户的请求第一次分发到哪台Tomcat后,后继的请求会一直分发到此Tomcat服务器上处理。这样设的坏处是,当相应的tomcat挂掉,那么session就会丢失。如果设为false,则表明需求会话复制。

E、worker.loadbalancer.sticky_session_force=true

   如果上面的sticky_session设为true时,建议此处也设为true,此参数表明如果集群中某台Tomcat服务器在多次请求没有响应后, 是否将当前的请求,转发到其它Tomcat服务器上处理;此参数在sticky_session=true时,影响比较大,会导致转发到其它Tomcat 服务器上的请求,找不到原来的session,所以如果此时请求中有读取session中某些信息的话,就会导致应用的null异常。

 
 


 

接下来便是 URI 的映射配置了,我们需要指定哪些链接是由 Tomcat 处理的,哪些是由 Apache 直接处理的,看看下面这个文件你就能明白其中配置的意义

 

/*= route1

/jkstatus=status

 

!/*.gif= route1

!/*.jpg= route1

!/*.png= route1

!/*.css=route1

!/*.js=route1

!/*.htm=route1

!/*.html=route1
 


 

相信你已经明白了一大半了:所有的请求都由route1这个 worker 进行处理,但是有几个例外,/jkstatus 请求由 status 这个 worker 处理。另外这个配置中每一行数据前面的感叹号是什么意思呢?感叹号表示接下来的 URI 不要由 JK 进行处理,也就是 Apache 直接处理所有的图片、css 文件、js 文件以及静态 html 文本文件。

 

以上的 workers.properties 配置就是我们前面那个屏幕抓图的页面所用的配置。首先我们配置了两个类型为 ajp13 的 worker 分别是 s1 和s2,它们指向同一台服务器上运行在两个不同端口 8009 和 8109 的 Tomcat 。不需要设置Tomcat中的jvmRoute, 只要正确设置了port和host,apache便能正确连接tomcat。接下来我们配置了一个类型为 lb(也就是负载均衡的意思)的 worker,它的名字是route1,这是一个逻辑的 worker,它用来管理前面配置的两个物理连接s1 和s2。最后还配置了一个类型为 status 的 worker,这是用来监控 JK 本身的模块。有了这三个 worker 还不够,我们还需要告诉 JK,哪些 worker 是可用的,所以就有 worker.list = route1, status 这行配置。

Apache的mod_deflate模块提供了DEFLATE输出过滤器,允许服务器在将输出内容发送到客户端以前进行压缩,以节约带宽。

 

LoadModule deflate_module modules/mod_deflate.so

<Location />

SetOutputFilter DEFLATE

</Location>

 

压缩是由DEFLATE过滤器实现的。下面的指令会对其所在容器中的文档启用压缩:

SetOutputFilter DEFLATE

一些流行的浏览器不能正确处理所有压缩内容,因此你可能需要将gzip-only-text/html标记设为"1"来仅仅允许压缩html文件(见下面)。如果你设置了"1"以外的任何值,都将被忽略。

如果你想将压缩限制在几种特定的MIME类型上,可以使用AddOutputFilterByType指令。下面的例子仅仅允许对html文档进行压缩:

<Directory "/your-server-root/manual">
AddOutputFilterByType DEFLATE text/html
</Directory>

对于那些不能正确处理所有压缩内容的浏览器,可以使用BrowserMatch指令针对特定的浏览器设置no-gzip标记以取消压缩。为了取得更好的效果,你可以将no-gzip和gzip-only-text/html配合使用。在这种情况下,下面的设置将会覆盖上面的设置。看看从配置示例中摘录的片断:

BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

第一条指令表示如果User-Agent字符串表示它是一个Navigator 4.x的浏览器,这种浏览器不能正确处理除text/html之外的所有类型。而4.06, 4.07, 4.08版的Navigator完全不能处理任何压缩内容,因此第二条指令对这些浏览器完全禁用压缩。

第三个BrowserMatch指令修正了上面两条对浏览器的推测,因为微软的IE也将它自己标识成"Mozilla/4"但是它实际上能够处理所有的压缩内容。因此又在User-Agent头中额外匹配了字符串"MSIE"("\b"表示"单词边界"),并且取消了前面的限制。

 

注意
通过SetEnv设置force-gzip环境变量将会忽略浏览器的"accept-encoding",始终发送经过压缩的内容。

posted @ 2011-03-18 23:34  玩玩乐乐  阅读(1314)  评论(0编辑  收藏  举报