标签:tomcat负载均衡 基于mod_jk 基于mod_proxy
概述
Tomcat是一个完全功能的HTTP服务器,能够独立完成接收客户端请求,处理请求,然后封装响应报文响应客户端。但是Tomcat的并发响应能力并不强,所以往往使用httpd或nginx服务器用于在前端接收客户端请求,然后将请求调度至后端多个Tomcat节点。本文介绍的是利用httpd作为反向代理服务器,实现Tomcat的负载均衡。
httpd连接后端的Tomcat服务器,需要启用对应的模块。能够实现该功能的有两个模块:mod_proxy,mod_jk。mod_proxy是新出的模块,只有在apache 2.2及之后的版本上才可以使用,但是相对于mod_jk模块,它可以提供更丰富的功能和安全性。
实现过程
拓补图:
实验环境:
httpd:192.168.1.116
Tomcat node1:192.168.1.106
Tomcat node2:192.168.1.127
在Tomcat node1和node2上安装JDK和tomcat,完成环境变量的配置(192.168.1.106和192.168.1.127上完成)。
安装jdk:
[root@node1 ~]# rpm -ivh jdk-7u9-linux-x64.rpm [root@node1 ~]# cd /usr/java/ [root@node1 java]# ll total 4 lrwxrwxrwx 1 root root 16 Sep 1 07:56 default -> /usr/java/latest drwxr-xr-x 10 root root 4096 Sep 1 07:56 jdk1.7.0_09 lrwxrwxrwx 1 root root 21 Sep 1 07:56 latest -> /usr/java/jdk1.7.0_09
在/usr/java目录下有个latest链接文件指向最新的JDK。配置环境变量时直接使用此路径。
配置环境变量:
[root@node1 ~]# vim /etc/profile.d/java.sh export JAVA_HOME=/usr/java/latest export PATH=$JAVA_HOME/bin:$PATH ################################# [root@node1 ~]# . /etc/profile.d/java.sh
安装tomcat:
[root@node1 ~]# tar xf apache-tomcat-7.0.42.tar.gz -C /usr/local/
环境变量配置:
[root@node3 local]# cd /usr/local [root@node3 local]# ln -sv apache-tomcat-7.0.42/ tomcat `tomcat‘ -> `apache-tomcat-7.0.42/‘ [root@node1 ~]# vim /etc/profile.d/tomcat.sh export CATALINA_HOME=/usr/local/tomcat export PATH=$CATALINA_HOME/bin:$PATH #################################### [root@node1 ~]# . /etc/profile.d/tomcat.sh
为tomcat提供服务脚本:
#!/bin/sh # Tomcat init script for Linux. # # chkconfig: 2345 96 14 # description: The Apache Tomcat servlet/JSP container. # JAVA_OPTS=‘-Xms64m -Xmx128m‘ JAVA_HOME=/usr/java/latest CATALINA_HOME=/usr/local/tomcat export JAVA_HOME CATALINA_HOME case $1 in start) exec $CATALINA_HOME/bin/catalina.sh start ;; stop) exec $CATALINA_HOME/bin/catalina.sh stop;; restart) $CATALINA_HOME/bin/catalina.sh stop sleep 2 exec $CATALINA_HOME/bin/catalina.sh start ;; *) echo "Usage: `basename $0` {start|stop|restart}" exit 1 ;; esac
在代理服务器上编译安装apache2.4(192.168.1.116上)。
首先安装apr和apr-util:
[root@www ~]# tar xf apr-1.5.0.tar.bz2 [root@www ~]# cd apr-1.5.0 [root@www apr-1.5.0]# ./configure --prefix=/usr/local/apr-1.5.0 [root@www apr-1.5.0]# make && make install ######################################### [root@www ~]# tar xf apr-util-1.5.3.tar.bz2 [root@www ~]# cd apr-util-1.5.3 [root@www apr-util-1.5.3]# ./configure --prefix=/usr/local/apr-util-1.5.3 --with-apr=/usr/local/apr-1.5.0/ [root@www apr-util-1.5.3]# make && make install
安装httpd-2.4:
[root@www ~]# tar xf httpd-2.4.9.tar.bz2 [root@www ~]# cd httpd-2.4.9 [root@www httpd-2.4.9]# yum install pcre-devel -y [root@www httpd-2.4.9]# ./configure --prefix=/usr/local/apache --sysconfdir=/etc/httpd --e nable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/usr/l ocal/apr-1.5.0/ --with-apr-util=/usr/local/apr-util-1.5.3/ --enable-mpms-shared=all --with-m pm=event --enable-proxy --enable-proxy-http --enable-proxy-ajp --enable-proxy-balancer --enable-lbmethod-heartbeat --enable-heartbeat --enable-slotmem-shm --enable-slotmem -plain --enable-watchdog [root@www httpd-2.4.9]# make && make install
在编译时需要添加这几个参数来启用对应的模块:--enable-proxy --enable-proxy-http --enable-proxy-ajp --enable-proxy-balancer,最后的几个参数用于实现httpd与后端tomcat之间的信号传递实现对其健康状态的检测。
安装完成之后启动服务查看对应的模块是加载:
[root@www ~]# httpd -D DUMP_MODULES | grep proxy proxy_module (shared) ..... proxy_http_module (shared) ..... proxy_ajp_module (shared) proxy_balancer_module (shared)
httpd基于mod_jk模块实现负载均衡
httpd可以通过2种协议连接tomcat:http,ajp。tomcat启动之后默认会监听在2个端口:8080,8009。8080用于接收http请求,8009则用于接收ajp请求。mod_jk模块仅支持使用ajp协议连接后端的tomcat。
由于mod_jk模块出现的较早,httpd默认不包括该模块,需要通过apache的apxs函数编译该模块,安装至apache的模块目录下。若是直接使用yum安装的httpd,需要安装httpd-devel以提供apxs函数。
在代理服务器节点上安装mod_jk模块(192.168.1.116上),tomcat-connectors-1.2.40-src.tar.gz即为其源码包。
[root@www ~]# tar xf tomcat-connectors-1.2.40-src.tar.gz [root@www ~]# cd tomcat-connectors-1.2.40-src/native/ [root@www native]# ./configure --with-apxs=/usr/local/apache/bin/apxs [root@www native]# make && make install
编辑配置文件,httpd-jk.conf默认在extra目录下没有,需要自己创建:
[root@www ~]# vim /etc/httpd/extra/httpd-jk.conf LoadModule jk_module modules/mod_jk.so #加载mod_jk模块 JkWorkersFile /etc/httpd/extra/workers.properties #定义后端每个tomcat实例的特性 JkLogFile logs/mod_jk.log #指定mod_jk模块的日志文件 JkLogLevel error #记录日志的级别(info, error, debug) JkMount /* lbcluster #将所有路径代理至lbcluster这个worker JkMount /status/ stat #状态信息页
上述的配置参数中,jkWorkersFile用于指定保存了后端各个Tomcat工作属性定义的配置文件。该配置文件的文件名通常是workers.properties,该文件中每一个tomcat实例视为一个worker,在apache启动时mod_jk会读取该配置文件的信息获取每个worker的配置信息。
workers.properties文件的配置格式:
worker.list = < a comma separated list of worker names >
worker. <worker name> .<property> = <property value>
worker.list为worker列表,worker.<worker name>.<property>定义各个worker的名称和属性。
编辑workers.properties:
[root@www ~]# vim /etc/httpd/extra/workers.properties worker.list = lbcluster,stat worker.TomcatA.type = ajp13 #type指定worker的工作机制(定义一个tomcat实例) worker.TomcatA.host = 192.168.1.106 #host指定tomcat实例所在主机 worker.TomcatA.port = 8009 #port指定连接tomcat实例上的端口 worker.TomcatA.lbfactor = 5 #lbfactor指定该worker的权重 worker.TomcatB.type = ajp13 worker.TomcatB.host = 192.168.1.127 worker.TomcatB.port = 8009 worker.TomcatB.lbfactor = 5 worker.lbcluster.type = lb worker.lbcluster1.method = B #指定调度的算法(根据负载情况进行调度) worker.lbcluster.sticky_session = 0 #是否启用sticksession worker.lbcluster.balance_workers = TomcatA, TomcatB worker.stat.type = status #用于显示各worker的工作状态
其中type属性可定义3种工作机制:
ajp13 #定义一个tomcat实例
lb #用于负载均衡场景中,此worker包括多个tomcat实例
status #用于显示各个worker工作状态的特使worker
上述配置中定义了2个tomcat实例:TomcatA和TomcatB,lbcluster这个worker包括了这两个tomcat实例,根据httpd-jk.conf中的定义(JkMount /* lbcluster)所用的请求都将使用定义的算法调度至TomcatA和TomcatB。实现负载均衡的算法有3种,默认为“R”,根据用户的请求个数进行调度,“T”根据已发送给各tomcat的流量进行调度,“B”根据负载情况进行调度。
若将文件中的worker.lbcluster1.sticky_session = 0改为1,则将实现session绑定,同一客户端的所有后续请求都将直接调度至第一个访问的worker。
在httpd的主配置文件中包含上述完成的配置文件:
[root@www ~]# vim /etc/httpd/httpd.conf ..... Include /etc/httpd/extra/httpd-jk.conf
重新加载服务:
[root@www ~]# httpd -t Syntax OK [root@www ~]# service httpd reload
上述的配置都在httpd节点上完成,然后在后端tomcat节点上添加对应的虚拟主机和测试页面:
在Tomcat node1和node2上:
[root@node1 tomcat]# vim conf/server.xml ..... <Host name="www.xiaoxiao.com" appBase="/tomcat/webapps" unpackWARs="true" autoDeploy="true"> <Context path="/web" docBase="web"/> </Host> ###################################### [root@node1 ~]# cd /tomcat/webapps/ [root@node1 webapps]# mkdir web/WEB-INF/{classes,lib} -pv
在实现负载均衡时,若一个节点上有多个tomcat实例,这是需要在engine段加上jvmRoute参数,其值为httpd节点上/etc/httpd/extra/workers.properties中对应的worker name。例如:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="a"> <Engine name="Catalina" defaultHost="localhost" jvmRoute="b">
node1上的测试页面:
[root@node1 web]# vim index.jsp <%@ page language="java" %> <html> <head><title>Tomcat node1</title></head> <body> <h1><font color="blue">Tomcat node1</font></h1></p> </body> </html>
node2上的测试页面:
[root@node2 web]# vim index.jsp <%@ page language="java" %> <html> <head><title>Tomcat node2</title></head> <body> <h1><font color="red">Tomcat node2</font></h1></p> </body> </html>
配置完成后启动tomcat服务。访问测试:
状态页面:
配置完成后其自动实现了后端服务器健康状态的检测,某台服务器故障之后,可实时完成故障转移。
httpd基于mod_proxy模块实现负载均衡
mod_proxy模块支持通过http和ajp协议连接后端的tomcat。
在httpd节点上,配置httpd的全局段:
<proxy balancer://lbcluster> BalancerMember ajp://192.168.1.106:8009 loadfactor=1 route=a#指定后端服务器及权重(loadfactor) BalancerMember ajp://192.168.1.127:8009 loadfactor=1 route=b ProxySet lbmethod=bytraffic #调度使用的算法 #ProxySet stickysession=JSESSIONID #是否启用sticksession </proxy>
若使用http协议:
<proxy balancer://lbcluster1> BalancerMember http://192.168.1.106:8080 loadfactor=1 route=a BalancerMember http://192.168.1.127:8080 loadfactor=1 route=b #ProxySet stickysession=JSESSIONID ProxySet lbmethod=bytraffic </proxy>
在httpd节点上配置虚拟机:
[root@www httpd]# vim extra/httpd-vhosts.conf <VirtualHost *:80> ServerName www.xiaoxiao.com #虚拟主机名称 ProxyVia Off #在响应报文中是否添加via首部,用于表明这是经过哪个主机代理得到的响应 ProxyRequests Off #关闭正向代理(正反向代理不应该同时启用) ProxyPreserveHost On #代理将请求报文的host首部信息发送给后端服务器 ProxyPass / balancer://lbcluster/ #将请求代理至lbcluster包含的后端服务器 ProxyPassReverse / balancer://lbcluster/ <Location /status> #启用状态页面 SetHandler balancer-manager Proxypass ! #指定此路径不进行代理 Require all granted </Location> <Proxy *> Require all granted </Proxy> <Location / > Require all granted </Location> </VirtualHost>
在定义负载均衡的集群时,常用的参数有lbmethod(调度算法),maxattempts(故障转移次数),nofailover(是否失效转移),stickysession(用于保持session)。这些参数可以定义在全局段的proxy段中,如下:
<proxy balancer://lbcluster>
.......
ProxySet lbmethod=bytraffic
ProxySet stickysession=JSESSIONID
</proxy>
也可以定义在banlancer://或ProxyPass后面。
lbmethod能够指定的算法有3种:
byrequests #根据权重进行轮询
bytraffic #基于流量和权重进行调度
bybusyness #基于后端服务器的当前负载进行调度
在主配置文件中包含虚拟主机的配置文件,注销mod_jk的配置文件:
Include /etc/httpd/extra/httpd-vhosts.conf #Include /etc/httpd/extra/httpd-jk.conf
后端的tomcat按照上一个案例进行配置,然后重启httpd服务:
[root@www ~]# httpd -t Syntax OK [root@www ~]# service httpd reload
测试结果与上述一致,不同的是mod_proxy的状态信息页面功能更强大,可以在页面中对后端主机进行各属性的配置。
可以设置ProxySet stickysession=JSESSIONID将同一客户端请求定向至同一台后端服务器来维持session。根据个人的配置,貌似这个参数只能配置在全局段的proxy段中,且BalancerMember后面还需要添加route参数,才能生效。
<proxy balancer://lbcluster>
.......
ProxySet stickysession=JSESSIONID
</proxy>
在负载均衡过程中,如果后端一个节点下线,则原本代理至该服务器的请求将调度至其他节点,这时用户的session将损坏。可以关闭nofailover(nofailover = Off)不进行失效转移,能够保证节点重新上线后,用户能够访问到原来的session。
.................^_^
标签:tomcat负载均衡 基于mod_jk 基于mod_proxy
原文地址:http://ljbaby.blog.51cto.com/10002758/1691091