高性能Web服务之Httpd负载均衡Tomcat实现Session Sticky及Session Cluster

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高性能Web服务之Httpd负载均衡Tomcat实现Session Sticky及Session Cluster相关的知识,希望对你有一定的参考价值。

Httpd负载均衡Tomcat实现Session Sticky及Session Cluster架构如下所示:

技术分享

实现过程如下:

配置tomcat服务(tomcat1\tomcat2)

(1)安装JDK

# rpm -ivh jdk-7u9-linux-x64.rpm 
--安装JDK后生成的文件
# cd /usr/java/ ; ll
total 4
lrwxrwxrwx  1 root root   16 Sep 27 09:09 default -> /usr/java/latest
drwxr-xr-x 10 root root 4096 Sep 27 09:09 jdk1.7.0_09
lrwxrwxrwx  1 root root   21 Sep 27 09:09 latest -> /usr/java/jdk1.7.0_09

--配置JDK环境变量
# vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/jdk1.7.0_09
export PATH=$PATH:$JAVA_HOME/bin
--执行使环境变量生效
# . /etc/profile.d/java.sh
--测试如下:
# java -version
java version "1.7.0_45"        --jdk版本
OpenJDK Runtime Environment (rhel-2.4.3.3.el6-x86_64 u45-b15)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)

(2)安装tomcat

--解压tomcat包至/usr/local下
# tar xf apache-tomcat-7.0.72.tar.gz -C /usr/local/
# cd /usr/local/
# ln -sv apache-tomcat-7.0.72 tomcat
--配置tomcat环境变量
# vim /etc/profile.d/tomcat.sh
export CATALINA_HOME=/usr/local/tomcat
export PATH=$PATH:$CATALINA_HOME/bin
# . /etc/profile.d/tomcat.sh
--测试如下:
# catalina.sh version
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/java/jdk1.7.0_09
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Server version: Apache Tomcat/7.0.67
Server built:   Dec 7 2015 13:07:11 UTC
Server number:  7.0.72.0
OS Name:        Linux
OS Version:     2.6.32-431.el6.x86_64
Architecture:   amd64
JVM Version:    1.7.0_09-b05
JVM Vendor:     Oracle Corporation

--为tomcat提供srv启动脚本
# vim /etc/init.d/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)
  $CATALINA_HOME/bin/catalina.sh start;;
stop)
  $CATALINA_HOME/bin/catalina.sh stop;;
restart)
  $CATALINA_HOME/bin/catalina.sh stop
  sleep 2
  $CATALINA_HOME/bin/catalina.sh start;;
*)
  echo "Usage: `basename $0` {start|stop|restart}"
  exit 1
  ;;
esac

# chmod +x /etc/init.d/tomcat
# chkconfig --add tomcat
# service tomcat start

--检查tomacat默认监听端口如下所示:
# ss -tunlp | grep java
tcp    LISTEN     0      100                   :::8080                 :::*      users:(("java",19525,42))
tcp    LISTEN     0      1       ::ffff:127.0.0.1:8005                 :::*      users:(("java",19525,47))
tcp    LISTEN     0      100                   :::8009                 :::*      users:(("java",19525,43))

(3)配置虚拟主机如下所示(两台tomcat都要配置):

# vim /usr/local/tomcat/conf/server.xml 
#设置默认虚拟主机为www.samlee.com #第二台tomcatserver的jvmRoute设置为TomcatB
<Engine name="Catalina" defaultHost="www.samlee.com" jvmRoute="TomcatA">
#添加虚拟主机:
<Host name="www.samlee.com" appBase="/web/webapps/" unpackWARS="true" autoDeploy="true">
  <Context path="" docBase="/web/webapps" reloadable="true" />
   <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/web/logs"
      prefix="samlee_access_log." suffix=".txt"
      pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>

#创建虚拟主机目录:
# mkdir -pv /web/webapps/{WEB-INF,META-INF,classes,lib}

(4)创建网页文件(两台tomcat都要配置):

tomcatA:
# vim /web/webapps/index.jsp
<%@ page language="java" %>
<html>
  <head><title>TomcatA</title></head>
  <body>
    <h1><font color="red">TomcatA.samlee.com</font></h1>
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("samlee.com","samlee.com"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>

tomcatB:
# vim /web/webapps/index.jsp
<%@ page language="java" %>
<html>
  <head><title>TomcatB</title></head>
  <body>
    <h1><font color="blue">TomcatB.samlee.com</font></h1>
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("samlee.com","samlee.com"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>

重启tomcat服务部署:

# service tomcat stop
# service tomcat start

访问测试如下:

技术分享

技术分享


配置httpd 实现负载均衡反向代理tomcat

配置文件如下所示:

# vim /etc/httpd/conf.d/proxy.conf
<Proxy balancer://lbcluster>
  BalancerMember ajp://192.168.56.11:8009 loadfactor=1 route=TomcatA
  BalancerMember ajp://192.168.56.12:8009 loadfactor=1 route=TomcatB
</Proxy>

<VirtualHost *:80>
  ServerName www.samlee.com
  ProxyVia on
  ProxyRequests off
  ProxyPassReverse / balancer://lbcluster/
  ProxyPass / balancer://lbcluster/
</VirtualHost>

重启httpd服务访问测试如下所示:

# service httpd restart

测试如下:

技术分享

以上我们可以看到反向代理及负载均衡已经生效。


配置httpd 实现session sticky会话绑定

如果tomcat运行着一个动态站点, 那么上面这种byrequest的负载均衡调度算法就有很大问题了, 可能刚登录站点再刷新又回到没有登录的状态了, 所以我们就要实现session sticky, 其实session sticky就是我们之前lvs的sh算法, 和nginx的ip_hash实现的效果

配置文件如下所示:

# vim /etc/httpd/conf.d/proxy.conf
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://lbcluster>
  BalancerMember ajp://192.168.56.11:8009 loadfactor=1 route=TomcatA
  BalancerMember ajp://192.168.56.12:8009 loadfactor=1 route=TomcatB
  ProxySet stickysession=ROUTEID
</Proxy>

<VirtualHost *:80>
  ServerName www.samlee.com
  ProxyVia on
  ProxyRequests off
  ProxyPassReverse / balancer://lbcluster/
  ProxyPass / balancer://lbcluster/
</VirtualHost>

重启httpd服务访问测试如下所示:

# service httpd restart

测试如下:

技术分享

如上图所示,显示已经成功将session会话绑定在tomcatA主机上了。


配置tomcat实现session cluster 会话信息共享复制:

  *使用session sticky会有很多问题, 如果某台主机宕机了, 那么用户的session就丢失了, 所以我们还可以通过session cluster保存用户会话.

  **什么是Session Cluster?? 正常情况下session信息是保存在用户所访问的服务器上,服务器宕机, 用户的session就丢失了, 但是我们可以通过session cluster的方式来实现将用户的session信息保存在后端所有的服务器上, 这样来, 无论用户在访问哪一台服务器,session都不会丢失.


四种常见的session manager

**StandardManager
**PersistentManager: 可以将session信息保存在持久存储中
**DeltaManager: 将session信息通过多播的形式共享到其他节点
**BackupManager: 将session信息共享到特定的一个节点上

在配置tomcat前,先将httpd配置的session sticky取消:

构建DeltaManager集群步骤:
    1、在各节点的server.xml的engine或host容器添加如上内容;注意修改MemberShip组件中的多播地址address="228.0.0.4",建议修改Receiver中的address为本机能够传递心跳信息的地址;
    2、在各节点为使用组播地址添加组播路由,格式:
        route add -net $MCAST_ADDRESS netmask 255.255.255.255 dev eth0
    3、在相应应用程序的web.xml中添加<distributable\>;

编辑配置tomcat配置文件如下所示(两台tomcat主机都要配置):

下列内容放在<Host />内
    <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.1.7"
                    port="45564"
                    frequency="500"
                    dropTime="3000"/>
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                  address="192.168.56.12"   --这里修改该本机IP地址
                  port="4000"
                  autoBind="100"
                  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>

配置WEB-INF中的web.xml文件如下:

# cp /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml /web/webapps/WEB-INF/
# vim /web/webapps/WEB-INF/web.xml 
#添加下面这一行,在</web-app>内
<distributable/>

--复制配置文件web.xml至tomcatA主机上
# scp /web/webapps/WEB-INF/web.xml [email protected]1:/web/webapps/WEB-INF/
--复制配置文件server.xml至tomcatA主机上,并按要求修改IP地址及虚拟主机jvmRoute
# scp /usr/local/tomcat/conf/server.xml [email protected]:/usr/local/tomcat/conf/

为各tomcat节点添加组播路由地址(两台tomcat主机都要配置):

route add -net 228.0.1.7 netmask 255.255.255.255 dev eth0

重启tomcat服务

# service tomcat stop
# service tomcat start

访问测试如下所示:

技术分享

上图我们看到session会话ID访问后一直没有,证明已经配置会话共享成功了。

本文出自 “Opensamlee” 博客,请务必保留此出处http://gzsamlee.blog.51cto.com/9976612/1860175

以上是关于高性能Web服务之Httpd负载均衡Tomcat实现Session Sticky及Session Cluster的主要内容,如果未能解决你的问题,请参考以下文章

nginx反向代理及tomcat负载均衡

haproxynginx以及httpd负载均衡tomcat主机,seesion保持问题

负载均衡之Haproxy配置详解(及httpd配置)

Nginx+Tomcat负载均衡集群

Tomcat及负载均衡

部署Tomcat及负载均衡