1. 程式人生 > >tomcat的session會話保持方案

tomcat的session會話保持方案

RoCE 防火 farm tro 動態 未收到 配置文件 測試 tables

基礎知識

??

tomcat

??
??tomcat是Apache軟件基金會的Jakarta項目中的核心項目,最新的Servlet和JSP規範能夠在Tomcat中很好的表現。作為一個免費的開放源代碼的Web應用服務器,屬於輕量級的應用服務器,在中小型系統和並發量不是很大的場景下被廣泛使用,是開發和調試JSP代碼的首選。實際上而言,tomcat是Apache服務器的拓展,但是可以獨立運行,tomcat可以獨立的去處理html和jsp頁面。
??

memcached

??
??Memcached 是一個高性能的分布式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,但是客戶端可以用任何語言來編寫,並通過memcached協議與守護進程通信。這裏主要是做為tomcat的session存儲設備。

??

session

??
??在計算機中,尤其是在網絡應用中,稱為“會話控制”。Session 對象存儲特定用戶會話所需的屬性及配置信息。這樣,當用戶在應用程序的 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。當用戶請求來自應用程序的 Web 頁時,如果該用戶還沒有會話,則 Web 服務器將自動創建一個 Session 對象。當會話過期或被放棄後,服務器將終止該會話。

??在現今的互聯網架構中會話保持越來越重要,但是會話的保持卻在一定程度上依賴於提供服務的服務器上,隨著並發量的不斷提升,服務器最終會由於負載過高而宕機,因此引入了負載均衡機制,但是負載均衡的調度會使得同一用戶的請求被調度到不同的主機之上,會嚴重的影響到session的保存。

??

實驗模擬

??
這裏打算實現兩種session會話的保持方案。
一.Tomcat自身的session復制集群方案;
二.Tomcat+memcached的共享session保持方案。
??

實驗設備

??

ip地址 操作系統
nginx代理 192.168.99.131 CentOS7.4
tomcat1 192.168.99.130 CentOS7.4
tomcat2 192.168.99.240 CentOS7.4

??
環境配置
??
清空防火墻規則,關閉selinux,安裝jdk

#清空防火墻規則
iptables -F
iptables -X

#臨時設置關閉selinux
setenforce 0

#安裝jdk,centos7的源默認最高支持jdk1.8
yum install java-1.8.0-openjdk-devel -y

??

tomcat自身集群session復制實現會話保持

??

基礎知識

??
??在<engine>或者<host>配置啟用集群,使用Delta Manager to replicate session deltas 啟用所有的會話復制。通過all-to-all,意味著會話會被復制到進群中的其他所有節點,這樣是設計適用於較小的集群,但是,並不建議在較大的集群上去部署,在使用delta管理器的時候,它將會復制到所有的節點上,甚至是還沒有部署應用程序的節點。官方默認提供了一個backupManager的管理器,這個管理器的作用是僅僅將會話數據復制到一個備份節點上,而且,僅僅復制到已經部署了應用的節點,但是這個管理器目前仍在測試階段,不能保證其正常運行。
??

設計示意圖

??
技術分享圖片
??

開始部署

??

一.配置反向代理層nginx

??
1.安裝nginx並設置代理

#安裝nginx,nginx在epel源,因此未安裝epel源的話要先安裝epel源
yum instll nginx -y

2.修改默認的nginx配置文件

vim /etc/nginx/nginx.conf

技術分享圖片
3.編輯代理配置文件

 vim /etc/nginx/conf.d/proxy.conf 

upstream web {
        server 192.168.99.130:80;
        server 192.168.99.240:80;
}

server {
        listen 80 default_server;
        index index.jsp index.html;
        server_name douma.com;
        location / {
                proxy_pass http://web;
        }
}

技術分享圖片

4.檢查語法並啟動nginx

#檢查語法
nginx -t

#檢查無誤後啟動nginx
systemctl start nginx 

技術分享圖片
??

二.配置tomcat1

??
1.安裝tomcat以及對應的其他管理工具

yum install tomcat tomcat-lib tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp -y

2.配置tomcat顯示session會話信息

mkdir -pv /appdata/webapps/ROOT/{lib,classes,WEB-INF}

#編寫session會話顯示頁
vim /appdata/webapps/ROOT/index.jsp

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

#復制全局web.xml到對應目錄並修改
cp /etc/tomcat/web.xml  /appdata/webapps/ROOT/WEB-INF/

#編輯web.xml
添加<distributable/>字段

技術分享圖片

3.修改server.xml配置文件

vim /etc/tomcat/server.xml 

        <Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="douma.com_access_log." suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />

       <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.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                        address="192.168.99.130"  #這裏改為本機地址
                        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>

        </Host>

4.啟動tomcat並訪問8080端口

    systemctl start tomcat

技術分享圖片

5.安裝nginx

yum install nginx -y

6.編寫反代配置

#編輯默認配置文件取消default_server

技術分享圖片

#添加反代配置
vim /etc/nginx/conf.d/proxy.conf 

upstream web {
        server 192.168.99.130:8080;
}
server {
        listen 80 default_server;
        server_name douma.com;
        location / {
                index index.jsp index.html;
                proxy_pass http://web;
        }
}

技術分享圖片

7.啟動nginx

systemctl start nginx

技術分享圖片
??

三.配置tomcat2

??
基本配置和tomcat1相同,僅僅需要在編寫頁面,配置nginx代理配置和配置集群服務時候修改ip地址。

vim /appdata/webapps/ROOT/index.jsp 

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

驗證
技術分享圖片
??

驗證是否能夠共享session

??
訪問前端nginx調度器
技術分享圖片
刷新一下
技術分享圖片
雖然刷新了頁面,也同時由另一臺服務器響應,但是session會話信息還是很好的保存下來了。
??

配置文件介紹

??

#classname配置tomcat集群在進行信息傳遞時互相使用什麽類來進行傳遞;channelsendoptions可以設置為2,4,8.10;
 #2表示確認發送 Channel.SEND_OPTIONS_USE_ACK
 #4表示同步發送Channel.SEND_OPTIONS_SYNCHRONIZED_ACK 
 #8表示你異步發送Channel.SEND_OPTIONS_ASYNCHRONOUS
 #10表示 在異步模式下,可以通過加上確認發送(Acknowledge)來提高可靠性

 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                channelSendOptions="8">

#manager決定如何管理集群的session信息,
#className-指定實現org.apache.catalina.ha.ClusterManager接口的類,信息之間的管理.
#expireSessionsOnShutdown-設置為true時,一個節點關閉,將導致集群下的所有Session失效
#notifyListenersOnReplication-集群下節點間的Session復制、刪除操作,是否通知session listeners
#maxInactiveInterval-集群下Session的有效時間(單位:s)。
#maxInactiveInterval內未活動的Session,將被Tomcat回收。默認值為1800s
        <Manager className="org.apache.catalina.ha.session.DeltaManager"
                expireSessionsOnShutdown="false"
                notifyListenersOnReplication="true"/>
#Channel是Tomcat節點之間進行通訊的工具。
#Channel包括5個組件:Membership、Receiver、Sender、Transport、Interceptor
        <Channel className="org.apache.catalina.tribes.group.GroupChannel">

#Membership維護集群的可用節點列表。它可以檢查到新增的節點,也可以檢查到沒有心跳的節點
#className-指定Membership使用的類
#address-組播地址
#port-組播端口
#frequency-發送心跳(向組播地址發送UDP數據包)的時間間隔(單位:ms)。默認值為500
#dropTime-Membership在dropTime(單位:ms)內未收到某一節點的心跳,則將該節點從可用節點列表刪除。默認值為3000     
        <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
#Receiver : 接收器,負責接收消息BioReceiver(阻塞式)、NioReceiver(非阻塞式)
#className-指定Receiver使用的類
#address-接收消息的地址(默認是自動,但是最好手動更改為本地網卡對外ip)
#port-接收消息的端口
#autoBind-端口的變化區間
#如果port為4000,autoBind為100,接收器將在4000-4099間取一個端口,進行監聽
#selectorTimeout-NioReceiver內輪詢的超時時間
#maxThreads-線程池的最大線程數
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                        address="192.168.99.240"
                        port="4000"
                        autoBind="100"
                        selectorTimeout="5000"
                        maxThreads="6"/>
#sender:發送器負責發送消息 sender內嵌了transport組件,transport組件是負責真正傳送消息
        <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
 #Transport分為兩種:bio.PooledMultiSender(阻塞式)、nio.PooledParallelSender(非阻塞式) 
                <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
        </Sender>

 #MessageDispatch15Interceptor-查看Cluster組件發送消息的方式是否設置為Channel.SEND_OPTIONS_ASYNCHRONOUS(Cluster標簽下的channelSendOptions為8時)。
 #當設置為Channel.SEND_OPTIONS_ASYNCHRONOUS時,MessageDispatch15Interceptor先將等待發送的消息進行排隊,然後將排好隊的消息轉給Sender
        <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
        <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
        </Channel>

#Valve :可以作為過濾器,ReplicationValve-在處理請求前後打日誌;過濾不涉及Session變化的請求。   #vmRouteBinderValve-Apache的mod_jk發生錯誤時,保證同一客戶端的請求發送到集群的同一個節點
        <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                filter=""/>
        <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

#Deployer:同步集群下的所有節點的一致性
        <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                tempDir="/tmp/war-temp/"
                deployDir="/tmp/war-deploy/"
                watchDir="/tmp/war-listen/"
                watchEnabled="false"/>
#ClusterListener : 監聽器,監聽Cluster組件接收的消息,使用DeltaManager時,Cluster接收的信息通過ClusterSessionListener傳遞給DeltaManager
        <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
        <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>

??

tomcat+memcached實現session會話保持

??

設計架構圖

??
圖中的memcached在兩個tomcat節點都會安裝,來實現冗余。圖中獨立摘出來僅僅是為了方便理解。
技術分享圖片
??

開始部署

??

一.配置nginx代理

??
1.安裝nginx並設置代理

#安裝nginx,nginx在epel源,因此未安裝epel源的話要先安裝epel源
yum instll nginx -y

2.修改默認的nginx配置文件

vim /etc/nginx/nginx.conf

技術分享圖片
3.編輯代理配置文件

 vim /etc/nginx/conf.d/proxy.conf 

upstream web {
        server 192.168.99.130:80;
        server 192.168.99.240:80;
}

server {
        listen 80 default_server;
        index index.jsp index.html;
        server_name douma.com;
        location / {
                proxy_pass http://web;
        }
}

技術分享圖片

4.檢查語法並啟動nginx

#檢查語法
nginx -t

#檢查無誤後啟動nginx
systemctl start nginx 

技術分享圖片
??

二.配置tomcat1節點

??
1.安裝nginx配置本地代理

yum install nginx -y

    #編輯默認配置文件取消default_server
    vim /etc/nginx/nginx.conf

    #創建新的代理配置文件
    vim /etc/nginx/conf.d/proxy.conf

    upstream web {
        server 192.168.99.130:8080;
}
server {
        listen 80 default_server;
        server_name douma.com;
        location / {
                index index.jsp index.html;
                proxy_pass http://web;
        }
}

#語法檢查無誤後啟動nginx
nginx -t
systemctl start nginx

2.安裝tomcat和其他管理工具

yum install tomcat tomcat-lib tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp -y

3.創建測試項目

mkdir -pv /appdata/webapps/ROOT/{lib,classes,WEB-INF}

#創建測試頁面
vim /appdata/webapps/ROOT/index.jsp

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

#拷貝默認web.xml文件到新建目錄
cp /etc/tomcat/web.xml /appdata/webapps/ROOT/WEB-INF/

#修改web.xml文件添加<distributable/>字段

技術分享圖片

4.配置memcached的session會話保持

#安裝軟件包
yum install memcached -y

#下載msm的對應jar包

技術分享圖片

將下載的包放置到/usr/share/java/tomcat下

技術分享圖片

5.修改server.xml文件

 vim /etc/tomcat/server.xml 

 #配置虛擬主機
 <Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="douma.com_access_log." suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />
     </Host>                         

 #在host字段內添加

 <Context path="/" docBase="ROOT" reloadable="">
                <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
 #memcached的節點名(節點名自己定義,僅僅是顯示)和對應ip端口     
 memcachedNodes="n1:192.168.99.130:11211,n2:192.168.99.240:11211"
 #備用節點設置
                failoverNodes="n1"
                requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
                transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
                />
        </Context>

技術分享圖片
6.啟動tomcat

systemctl start tomcat

7.驗證
技術分享圖片
??

三.配置tomcat2節點

??
配置基本同配置tomcat1,要註意修改nginx代理後端的ip

nginx proxy.conf
upstream web {
        server 192.168.99.240:8080;
}
server {
        listen 80 default_server;
        server_name douma.com;
        location / {
                index index.jsp index.html;
                proxy_pass http://web;
        }
}

server.xml
<Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="douma.com_access_log." suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />

        <Context path="/" docBase="ROOT" reloadalbe="">
                <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
                memcachedNodes="n1:192.168.99.130:11211,n2:192.168.99.240:11211"
                failoverNodes="n1"
                requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
                transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
                />
        </Context>
        </Host>

技術分享圖片
技術分享圖片
??

四.配置完成後驗證

??
訪問代理服務器192.168.99.131

技術分享圖片
技術分享圖片

msm包的分享鏈接
https://pan.baidu.com/s/10k85xdXh2_7neCtfr9LNsQ

tomcat的session會話保持方案