高性能Web服務之Httpd負載均衡Tomcat實現Session Sticky及Session Cluster

Httpd負載均衡Tomcat實現Session Sticky及Session Cluster架構如下所示:

wKioL1f3ajTxPkM9AADT2sKTejY987.png

實現過程如下:

配置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

訪問測試如下:

wKiom1f3cOzTF69NAAC-rAEnpUg512.png

wKioL1f3cO_jPD00AADBjw-xilA024.png


配置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
  ProxyPa***everse / balancer://lbcluster/
  ProxyPass / balancer://lbcluster/
</VirtualHost>

重啓httpd服務訪問測試如下所示:

# service httpd restart

測試如下:

wKiom1f4abmQh3DxAAE-RqgzfK8266.gif

以上我們可以看到反向代理及負載均衡已經生效。


配置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
  ProxyPa***everse / balancer://lbcluster/
  ProxyPass / balancer://lbcluster/
</VirtualHost>

重啓httpd服務訪問測試如下所示:

# service httpd restart

測試如下:

wKioL1f4dBihp0dFAADDS9gYluY866.gif

如上圖所示,顯示已經成功將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]:/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

訪問測試如下所示:

wKiom1f4gY7jT5pZAAEW7R4l5fo298.gif

上圖我們看到session會話ID訪問後一直沒有,證明已經配置會話共享成功了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章