Tomcat集群使用Memcached實現Session共享
用戶訪問服務器資源主要分成兩類,一類是無狀態訪問,例如請求一張圖片。另一類是有狀態訪問,這種情況下,服務器需要記錄追蹤用戶狀態,並根據用戶所處狀態做出不同響應,典型的例子是購物車。Session的作用就是在Web服務器上保持用戶的狀態信息。
Tomcat集群為什麽需要Session共享?
當客戶端訪問Tomcat集群時,所有的請求將被Nginx攔截,由Nginx做負載均衡後轉發給後臺真實Tomcat。按照這個流程就可能出現一個問題,當用戶進行頁面刷新或跳轉時,每次請求將被轉發給不同的Tomcat處理,這樣就會造成Session的不同步。舉個簡單的栗子,例如當用戶往購物車添加商品時,興高采烈地準備買單了,當他跳轉到付款頁面卻發現購物車被清空了,這就是Session丟失的典型栗子。因此,我們需要為集群環境做Session同步。
Session共享方案討論
在服務器集群的環境下,共享Session的方案主要分為4類:
1.用戶端本地保存Cookie
在這種方式下,Web應用會將用戶狀態寫到Cookie並保存到用戶本地。但是,如果用戶使用的瀏覽器不支持Cookie或者禁用Cookie,該方案將會失效。並且Cookie能保存的數據是有大小限制的,而且數據暴露給用戶本地瀏覽器,存在安全性問題。
2.采用數據庫方式保存Session
相對本地Cookie方式,將用戶信息保存到服務端數據庫解決了數據安全性問題。然而,這麽做是有代價的,應用中所有對Session的訪問都必須經過數據庫,加大數據庫負擔,導致系統整體性能降低。
3.代理服務器
通過代理服務器實現Session共享的思路非常簡單,就是Session數據在哪臺Tomcat,之後的請求都轉發到這臺Tomcat。例如Nginx,具體實現只需要修改轉發規則為ip_hash
即可。但這時候可能存在某一時間段大量用戶始終訪問某臺Tomcat的負載很大,也就失去了負載均衡的意義。
4.搭建緩存服務器
這種方案也是應用最普遍的方案,通過搭建緩存服務器,並使用第三方工具接管Tomcat對Session的管理。
進
行Session管理,使用的緩存服務器是Memcached,並使用memcached-session-manager管理Session。memcached-session-manager(以下簡稱msm)的使用方法很簡單,只需要根據Tomcat版本和序列化方式下載相應jar包,拷貝至Tomcat的lib目錄下,最後修改Tomcat配置文件,更換Session管理模塊即可。
memcached-session-manager項目地址,http://www.iteye.com/topic/1125301
Nginx+Tomcat+Memcached實現tomcat集群和session共享
過程:clients—>172.16.253.11-->(tomcatA,tomcatB)
負載均衡節點:172.16.253.11,192.168.159.11
tomcatA節點:172.16.253.13
tomcatB節點:172.16.253.14
memcache節點:172.16.253.12
如圖所示:
一、Tomcat配置:
Tomcat作為應用程序服務器,主要作用是處理jsp文件,因此需要提供一個用於測試的文件index.jsp以及對應版本的.jar包。主要是memcached-session-manager相關的jar包,和用於將前端的用戶的cookie信息序列化成”鍵-值”格式的工具。
①下載:jar文件至各tomcat節點的tomcat安裝目錄下的lib目錄中
ls /usr/share/tomcat/lib/
memcached-session-manager- 1.8.2.jar
memcached-session-manager-tc7- 1.8.2.jar
spymemcached- 2.10.2 .jar
msm-javolution-serializer- 1.8.2.jar
javolution- 5.5.1.jar
如下:
②安裝tomcat及相關的服務包
yum install java-1.7.0-openjdk-devel.x86_64 # 安裝jdk
yum install tomcat tomcat-lib tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp
③分別在兩個tomcat上的某host上定義一個用於測試的context容器,並在其中創建一個會話管理器,如下所示:
vim /etc/tomcat/server.xml
<Host name="node1.com" appBase="/data/webapps" autoDeploy="true">
<Context path="/test" docBase="/usr/local/tomcat/webapps/test" reloadable="true">
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:172.16.253.12:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
/>
</Context>
</Host>
④分別為兩個context提供測試頁面:
TomcatA:
mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}
vim /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" %>
<html>
<head><title>TomcatA</title></head>
<body>
<h1><font color="red">TomcatA.magedu.com</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>
TomcatB:
mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}
vim /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" %>
<html>
<head><title>TomcatB</title></head>
<body>
<h1><font color="blue">TomcatB.magedu.com</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>
測試目錄的結構如下:
二、Nginx配置:
對於nginx來說,這本實驗中只是起了調度的作用,即反向代理的作用,並沒有實現動靜分離,路徑重寫等操作,這裏主要是將客戶端的請求調度至後端應用程序服務器Tomcat。集體配置如下:
vim /etc/nginx/nginx.conf
http {
upstream centos {
# 定義服務器集群
server 172.16.253.13:8080;
server 172.16.253.14:8080;
}
server {
listen 80 ;
listen [::]:80 default_server;
server_name _;
root
/usr/share/nginx/html
;
include
/etc/nginx/default
.d/*.conf;
location / {
proxy_pass http://172.16.253.11;
# 將請求代理至後端Tomcat服務器
}
...
}
systemctl start nginx
三、Memcached配置
對於memcached服務器的配置其實很簡單,由於memcached自身不能夠主動存儲cookie信息,只需要在memcached服務器上安裝memcached服務就行,至於對數據進行序列化則是由前面的服務器來實現的。
yum install memcached
systemctl start memcached # 啟動服務
ss -tnl | grep 1121 # 檢查服務是否正常啟動
四、測試
http://172.16.253.11/test
我們在客戶端進行測試。在瀏覽器中輸入nginx的地址:刷新你會看到,訪問的內容發生了改變,但是cookie值並沒有發生改變。
Tomcat集群使用Memcached實現Session共享