MemCache在tomcat中實現交叉存儲
1.cookie和session
cookie
在網站中,http請求是無狀態的。也就是說即使第一次和服務器連接後並且登錄成功後,第二次請求服務器依然不能知道當前請求是哪個用戶。cookie的出現就是爲了解決這個問題,第一次登錄後服務器返回一些數據( cookie )給瀏覽器,然後瀏覽器保存在本地,當該用戶發送第二次請求的時候,就會自動的把.上次請求存儲的cookie數據自動的攜帶給服務器,服務器通過瀏覽器攜帶的數據就能判斷當前用戶是哪個了。cookie存儲的數據量有限,不同的瀏覽器有不同的存儲大小,但一般不超過4KB。因此使用cookie只能存儲一些小的數據。
session
session和cookie的作用有點類似,都是爲了存儲用戶相關的信息。不同的是,cookie是存儲在本地瀏覽器,而session存儲在服務器。存儲在服務器的數據會更加的安全,不容易被竊取。但存儲在服務器也有一定的弊端,就是會佔用服務器的資源,但現在服務器已經發展至今,一些session信息還是綽綽有餘的。
cookie和session結合使用
web開發發展至今,cookie和session的使用已經出現了一些非常成熟的方案。在如今的市場或者企業裏,一般有兩種存儲方式:
存儲在服務端:通過cookie存儲一個session_ id,然後具體的數據則是保存在session中。如果用戶已經登錄,則服務器會在cookie中保存一個session id,下次再次請求的時候,會把該session_ id攜帶上來,服務器根據session_ id在session庫中獲取用戶的session數據。就能知道該用戶到底是誰,以及之前保存的一些狀態信息。這種專業術語叫做server side session。
將session數據加密,然後存儲在cookie中。這種專業術語叫做client side session。flask採用的就是這種方式,但是也可以替換成其他形式
2.爲什麼需要實現交叉存儲
應用服務器的高可用架構設計主要基於服務無狀態這一特性,但是事實上,業務總是有狀態的,在交易類的電子商務網站,需要有購物車記錄用戶的購買信息,用戶購買請求都是向購物車中增加商品;在社交類的網站中,需要記錄用戶的當前登陸狀態,最新發布的消息及好友狀態等,用戶每次刷新頁面都需要更新這些信息。
但如果每次用戶刷新頁面後信息都被更新而找不到剛纔的狀態,比如我們寫博客寫了一半刷新了頁面,後端服務器輪詢,另一個後端開始服務而找不到剛纔的狀態,這顯然是不行的。
所以需要實現交叉存儲,把用戶的數據在兩個後端服務器的memcache中都存放一份,這樣就算某個服務器的tomcat忽然宕掉,另一個後端服務器工作時,用戶的數據也不會丟失。
爲了對數據的保存更加牢靠,我們選擇交叉存放session的方法,即將訪問tomcat1上的數據存放在memcache2中,將訪問tomcat2上的數據存放在memcache1中,這樣存放,當某個tomcat服務斷了之後,訪問它的客戶session並不會消失,而是存放在了對立的memcache,如果存放session的memcache壞了,那麼它的數據會立即切換到另一個memcached中
3.在tomcat中實現session共享
1. 編寫測試頁內容:
在server3 server4中:
cd /usr/local/tomcat/webapps/ROOT/ #tomcat默認發佈目錄
vim test.jsp
寫入:
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> session " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
%>
測試:
訪問192.168.43.73:8080/test.jsp和192.168.43.74:8080/test.jsp
訪問192.168.43.72/test.jsp #依舊輪詢
刷新後…
怎樣不發生輪詢呢?
不輪詢的設置:
在server2中:
cd /usr/local/lnmp/nginx/conf/
vim nginx.conf
寫入21行內容:
17 http {
18 include mime.types;
19 default_type application/octet-stream;
20 upstream tomcat {
21 ip_hash;
22 server 172.25.254.3:8080;
23 server 172.25.254.4:8080;
24 }
nginx -t
nginx -s reload
測試:
訪問192.168.43.72/test.jsp #不再輪詢
刷新n次都是server3
那麼,宕掉server3的服務器呢?
再次刷新…
刷新n次都是server4
4.怎樣實現交叉存儲呢?
在server3和server4中:
1. 把需要的安裝包放在指定目錄下:
cp * /usr/local/tomcat/lib/
注意:rm -fr memcached-session-manager-tc6-1.6.3.jar
這裏我用的是tomcat7版本,所以刪除6
修改測試頁內容:
server3中:
vim /usr/local/tomcat/conf/context.xml
寫入:
36 <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
37 memcachedNodes="n3:192.168.43.73:11211,n4:192.168.43.74:11211"
38 failoverNodes="n3"
39 requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
40 transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
41 />
42 </Context>
server4中:
vim /usr/local/tomcat/conf/context.xml
寫入:
36 <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
37 memcachedNodes="n3:192.168.43.73:11211,n4:192.168.43.74:11211"
38 failoverNodes="n4"
39 requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
40 transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
41 />
42 </Context>
server3:
server4:
安裝並開啓memcached:
yum install memcached -y
systemctl start memcached
netstat -anlp| grep memcached
重啓tomcat:
cd /usr/local/tomcat/
bin/shutdown.sh
bin/startup.sh
測試:
首先刷新頁面:當我們訪問server3的時侯出現n4,表示已經把數據存放到了server4中
當我們訪問server4的時侯出現n3,表示我們已經把數據存放到了server3中
當我們訪問http://192.168.43.72/test.jsp時:
可以看出,server4的數據保存在server3上
當使用bin/shutdown.sh命令將server3的tomcat服務宕掉時,再刷新頁面
因爲我們宕掉了server3 的tomcat,所以這時候由server4來提供服務,而剛剛的數據保存在了server3的服務器上,我們可以看出,這時候server3的數據被保存在了server4中,所以,即使server3的tomcat服務掛掉,我們也能從server4中獲取到我們的數據,我們之前的數據並不會丟失,而是被保存到了server4中,這樣就實現了交叉存儲。
注意:這裏是掛掉服務而不是整個服務器宕掉。因爲如果服務器宕掉的話,memcache也就掛掉了,就無法實現交叉存儲。