
網上有很多關于通過MSM(memcached session manager)實作memcached共享session的文章,但是很多都是東拼西湊,誤導别人。正巧最近有一個地方用到,特此總結一下。
MSM支援tomcat6,tomcat7,tomcat8,MSM支援兩種模式:sticky sessions(粘性session)和non-sticky sessions(非粘性session)。我用到的是sticky session,是以以下都按照sticky session
來介紹。叢集結構是2個tomcat執行個體節點,2個memcached執行個體節點
. / . machine1 . X . machine2 . / .
簡單說明下:tomcat1為主要把它的session存儲到memcached2上,而memcache2是運作在另一台主機上的(一般情況下,memcached是存tomcat1的session),隻有當memcached2不可用時,tomcat1才會把session存在memcached1上,也就是說memcached1是為了tomcat1做故障切換用的節點。這要的話,當machine1挂了的時候,session是不會丢失的。
接着我們考慮使用session的哪種序列化方式,預設的是使用java進行序列化,是由memcached-session-manager.jar這個jar包來提供的方法,而其它的序列化方式是由其它的jar包提供的。
首先是要安裝jdk和tomcat,這裡不再贅述,當然tomcat可以選擇支援native函數。在修改tomcat配置檔案之前,先把一些jar包放在 $CATALINA_HOME/lib/( WEB-INF/lib)目錄裡,再修改$CATALINA_HOME/conf/ (META-INF/context.xml)配置檔案。
我們使用的是memcached,是以需要 spymemcached-2.11.1.jar
補充:如果使用couchbase,需要添加以下jar包: couchbase-client-1.4.0.jar jettison-1.3.jar, commons-codec-1.5.jar, httpcore-4.3.jar,httpcore-nio-4.3.jar, netty-3.5.5.Final.jar
需要注意的是,如果你使用java内置的序列化方式,把jar放在$CATALINA_HOME/lib/裡即可。如果為了更好的性能,使用自定義的序列化方式,就要把其它jar包部署在具體java項目工程下的WEB-INF/lib裡。以下是四種session序列化方式對應需要的jar包
- kryo-serializer: msm-kryo-serializer, kryo-serializers-0.11 (0.11 is needed, as 0.20+ is for kryo2), kryo, minlog, reflectasm, asm-3.2
- javolution-serializer: msm-javolution-serializer, javolution-5.4.3.1
- xstream-serializer: msm-xstream-serializer, xstream, xmlpull, xpp3_min
- flexjson-serializer: msm-flexjson-serializer, flexjson
是以非粘性sessions 使用kryo序列化所需要增加的jar包如下:
雖然我使用的是kryo序列化方式 + 非粘性session,但是還是把粘性session一起介紹一下。
sticky sessions粘性session + kryo序列化
在machine1上有tomcat1和memcached1,tomcat的$CATALINA_HOME/conf/context.xml增加如下配置
...
參數failoverNodes="n1" 是用來告訴 MSM 把session優先存儲在 memcached2上,隻有當memcached2挂了的時候才會把session存在memcache1也就是配置檔案的n1裡。
假如整個machine1挂了,session還是可用,因為session是存在machine2的memcache2上,可以通過tomcat2對外提供服務。
machine2上的tomcat2的配置檔案隻要改成failoverNodes="n2"即可。
non-sticky sessions 非粘性session + kryo序列化
非粘性session是不需要配置failoverNodes,也就是故障切換節點的,是以session是由所有tomcat節點通過輪訓(round-robin )來提供服務的,session是不和某單個tomcat節點綁定,是以tomcat所有節點的都是一樣的,如下:
...
配置完成後重新啟動兩個節點上的不同tomcat服務。
tail -f /usr/local/tomcat/logs/catalina.out
兩個節點tomcat的啟動日志都正常。
測試的session.jsp頁面内容如下
SessionID:
SessionIP:
SessionPort:
浏覽器通路測試頁面
頁面擷取的和我chrome浏覽器截獲的cookie裡session id是一樣的,這裡補充下session id是儲存在cookie裡的。
多次重新整理頁面session.jsp,發現session id不變化,再檢視通路tomcat的通路日志,出現多條通路記錄(這裡補充說明,tomcat預設是關閉通路日志的,需要開啟,然後自定義日志格式。)但是session保持不變。
由于session預設是存在tomcat的jvm裡的,我們驗證一下memcached裡是不是真的存了這個session記錄,查詢memcached存的内容然後導出到檔案裡
echo "stats cachedump 3 0" | nc 192.168.203.167 11211 > session.txt grep '6EDE9D610F85926D0A5AD01A991DC84C-n1 ' session.txt
确認存在。
至此tomcat的MSM,共享session的工作就做完了,good luck!
您的【關注】與【轉發】就是我堅持下去的動力,麻煩各位了