在上一篇博客中,我們介紹了tomcat自帶的cluster組件配置session replication cluster,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13363590.html;session復制集群的原理就是通過多播通信的方式,把節點的session資訊發送給集群其他節點;這種session復制集群有一個缺陷,如果后端tomcat server 一旦增多,那么對于后端用于發送session資訊的網路會非常擁擠,到達一定的量以后,后端網路就可能癱瘓,這樣一來session復制集群就失效了;這其中的原因就是因為各個節點通過多播通信的方式發送session;為了解決這樣的問題,我們需要重新想辦法把用戶的session存起來;常用的解決方案就是找一臺服務器或一組服務器用來存用戶的session,在用戶訪問tomcat服務器時,后端tomcat服務器都到我們指定的服務器存取session,這樣一來不管前端調度器把請求調度到后端任何一臺server上,后端server都會去session服務器上存取session,通過這樣的方式,我們可以把用戶的資訊共享給其他節點;但是我們需要注意一點后端存盤session的服務器可能存在單點;常用作為session服務器的有memcached和redis;它們都是鍵值型別的資料庫,不同的是memcached它的值是流式化型別的資料,什么意思呢?也就是說往memcached資料庫里存放資料,必須把資料先通過流式化工具編碼成資料流,然后存入到memcached中,如果需要取資料出來,它需要再通過流式化工具還原成之前的資料;而redis的值相比memcached的值要豐富很多,它不需要流式化工具將資料編碼成資料流,它可以直接存到redis中;
msm是什么?它都全稱叫memcached session manager 該組件的作用就是用來解決session共享的;以下是官方介紹:memcached-session-manager是一個tomcat會話管理器,用于將會話保持在memcached或Redis中,用于高可用性,可伸縮性和容錯性的Web應用程式,它支持粘性和非粘性配置,并且當前與tomcat 6.x,7.x,8.x和9.x一起使用,對于粘性會話,支持會話故障轉移(tomcat崩潰),對于非粘性會話,這是默認設定(默認情況下,不同的tomcat為不同的請求提供會話服務),此外,通過會話遷移也支持memcached故障轉移(memcached崩潰),也不應有任何單點故障,因此當memcached失敗時,會話不會丟失;簡單講就是把tomcat的session資訊存放在memcached中,當后端tomcat宕機,它上面存放的session不會丟失,因為都存放到memcached中了,如果memcached是單點,它也支持多節點;其實memcached到多節點不是memcached自身到功能,它是通過使用memcached客戶端來實作到,其原理很簡單,就是通過客戶端把session同時寫到多個節點上去,默認情況只有一臺memcached作業,當或當節點故障時,它會立即切換到備用節點;
msm搭建
環境說明
| 名稱 | IP地址 | 埠 |
| 代理服務器nginx | 192.168.16.197 | 80 |
| tomcatA+memcached1 | 192.168.16.196 | 8080,11211 |
| tomcatB+memcached2 | 192.168.16.198 | 8080,11211 |
首先配置nignx 負載均衡tomcatA和tomcatB,然后在tomcatA和tomcatB上部署一個測驗應用,部署的程序和配置可以參考前邊的博客,我這里就不闡述了;https://www.cnblogs.com/qiuhom-1874/p/13337003.html;
在tomcatA,tomcatB上安裝memcached,并啟動memcached
[root@node01 ~]# yum install -y memcached Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.aliyun.com * updates: mirrors.aliyun.com base | 3.6 kB 00:00:00 docker-ce-stable | 3.5 kB 00:00:00 epel | 4.7 kB 00:00:00 extras | 2.9 kB 00:00:00 mariadb | 2.9 kB 00:00:00 updates | 2.9 kB 00:00:00 (1/2): epel/x86_64/updateinfo | 1.0 MB 00:00:00 (2/2): epel/x86_64/primary_db | 6.9 MB 00:00:01 Resolving Dependencies --> Running transaction check ---> Package memcached.x86_64 0:1.4.15-10.el7_3.1 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================================================================== Package Arch Version Repository Size ================================================================================================================================== Installing: memcached x86_64 1.4.15-10.el7_3.1 base 85 k Transaction Summary ================================================================================================================================== Install 1 Package Total download size: 85 k Installed size: 176 k Downloading packages: memcached-1.4.15-10.el7_3.1.x86_64.rpm | 85 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : memcached-1.4.15-10.el7_3.1.x86_64 1/1 Verifying : memcached-1.4.15-10.el7_3.1.x86_64 1/1 Installed: memcached.x86_64 0:1.4.15-10.el7_3.1 Complete! [root@node01 ~]# systemctl start memcached [root@node01 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:11211 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 100 [::]:8009 [::]:* LISTEN 0 128 [::]:11211 [::]:* LISTEN 0 100 [::]:8080 [::]:* LISTEN 0 128 [::]:22 [::]:* LISTEN 0 100 [::1]:25 [::]:* LISTEN 0 1 [::ffff:127.0.0.1]:8005 [::]:* [root@node01 ~]#
提示:在node02上也是上面的操作,啟動memcached后,如果能夠看到11211埠啟動起來了,說明memcached的環境就準備好了;
準備連接memcached所需要用到的jar包
#!/bin/bash wget https://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/2.3.2/memcached-session-manager-2.3.2.jar wget https://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager-tc7/2.3.2/memcached-session-manager-tc7-2.3.2.jar wget https://repo1.maven.org/maven2/de/javakaffee/msm/msm-kryo-serializer/2.3.2/msm-kryo-serializer-2.3.2.jar wget https://repo1.maven.org/maven2/de/javakaffee/kryo-serializers/0.45/kryo-serializers-0.45.jar wget https://repo1.maven.org/maven2/com/esotericsoftware/kryo/3.0.3/kryo-3.0.3.jar wget https://repo1.maven.org/maven2/com/esotericsoftware/minlog/minlog/1.2/minlog-1.2.jar wget https://repo1.maven.org/maven2/com/esotericsoftware/reflectasm/reflectasm/1.09/reflectasm-1.09.jar wget https://repo1.maven.org/maven2/org/ow2/asm/asm/5.2/asm-5.2.jar wget https://repo1.maven.org/maven2/org/objenesis/objenesis/2.6/objenesis-2.6.jar wget https://repo1.maven.org/maven2/net/spy/spymemcached/2.12.3/spymemcached-2.12.3.jarView Code
提示:我上面是把jar包的連接都整理到一個腳本中,我們可以直接進入到tomcat存放jar的位置,執行腳本,即可把對對應jar包下載到tomcat存放jar包的目錄下;通常yum安裝到tomcat它的jar存放地是/usr/share/java/tomcat/;msm的檔案地址https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration;

提示:這里需要注意點,我們點擊對應名稱時,它跳轉的地址是http,會導致我們訪問不到,解決辦法就是把http改成https就可以訪問到了;上面紅框中的jar包是msm中核心包,除了上面的三個包以外,還需要下載序列化的工具包組件,如下

提示:msm序列化工具支持kryo,javolution,xstream,flexjson,根據自己的需求下載對應的序列化工具組件包就行了;
下載好上面的核心包,驅動包,以及序列化工具包,接下來就可以在tomcat中配置連接memcached(tomcatA和tomcatB都要下載上面的jar包)
tomcatA上的配置


提示:以上配置表示,在訪問/myapp這個uri時啟動MemcachedBackupSessionManager的管理器,這個管理器就是用于存放session的;其中對于這個管理來說,里面有幾個屬性,memcachedNodes表示指定memcached節點的標識,IP地址和埠,如果是多個節點,節點和節點之間用逗號隔開即可;failoverNodes用于指定失敗轉移節點的標識,如上配置的是m1,這也就意味m2是活動節點;只有當m2宕機后,m1才會接替m2;requestUriIgnorePattern表示忽略匹配指定模式的請求uri資源;transcoderFactoryClass用于指定序列化工具的類,這個需要同我們之前的序列化工具名稱來;比如我們使用的是javolution虛擬化工具,我們需要把寫成transcoderFactory;
對于tomcatB的server.xml的配置除了jvmRoute的值不一樣外,其他配置都是一樣的;到此基于msm的session服務器就配置好了;
驗證:重啟tomcatA和tomcatB,然后用瀏覽器訪問nginx地址,看看通過nginx負載均衡后,訪問到后端server是怎么回應客戶端的?


訪問nginx所在主機地址的/myapp,看看會怎么回應客戶端?
首次訪問

第二次訪問

第三次訪問

第四次訪問

提示:從上面的訪問結果來看,第一次訪問會在回應報文添加一個set-cookie的首部,第二次訪問時,客戶端會通過請求首部cookie把之前的set-cookie的值攜帶上去訪問服務端,此時服務端收到客戶端發送過來的cookie,給客戶端回應了一個和第一次訪問時一樣的頁面;但是第二次并沒有回應首部set-cookie;第三次客戶端訪問服務端,攜帶之前的cookie,此時被調度到node02上進行回應了,在回應首部又給客戶端了一個set-cookie,和之前的值,變化的只有后面的jvmRoute的標識;頁面回應的中的sessionid的值和前一個session的值一樣;第四次訪問,客戶端就把第三次訪問回應的set-cookie的值攜帶上去訪問服務端,服務端又給它回應一個set-cookie的值,sessionID的值沒有變化,變化的只有后面的jvmRoute的值,此時頁面顯示的sessionID第三次的頁面一樣;不一樣的是一個是node01回應的,一個是node02回應的,說明調度器在輪詢的調度請求;這個和我們之前的session replication cluster 訪問結果一樣;
把memcached2停掉看看客戶端是否還可以訪問后端server?

用瀏覽器訪問看看會有什么變化?用剛才訪問的瀏覽器,接著訪問

提示:可以看到我們剛才的訪問并沒有什么影響;
換個瀏覽器訪問或者關閉之前的訪問,從新打開瀏覽器訪問

提示:可以看到換了一個瀏覽器后,我們再次訪問后面的memcached就是m1,說明本次訪問的session存放在m1上;
從新斷開原有的連接,重新啟動瀏覽器訪問服務端

提示:可以看到,從新打開瀏覽器訪問,回應的sessionID 還是以前的,只是m2變成了m1;這說明在m1上找到了對應的session,所以當之前訪問過服務端的客戶端再次訪問時,服務端會根據客戶端提供的cookie去session服務器上查找,如果session又對應的sessionID,那么就把之前的狀態回應給客戶端;這同時也說明了m1和m2上都存在之前客戶端訪問的所有session資訊;
恢復m2,看看對應訪問是否會從m2上取session?


提示:可以看到當m2存活后,m1又會自動處于備份狀態,客戶端訪問服務端也會從m2上面取session資訊;
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/24173.html
標籤:Linux
