nginx+tomcat會話保持方案探討

tomcat做為輕量級的java應用服務器,對靜態頁面和大併發的處理並不是很好。所以現在流行的做法是使用nginx+tomcat來實現動靜分離與負載均衡, 做負載均衡集群就要考慮會話保持。

一、Session概述

1、什麼是會話(session)?

答: Session是在無狀態的HTTP協議下,服務端記錄用戶狀態時用於標識具體用戶的機制。

http協議是無狀態的,無狀態就表明每一次客戶端的訪問請求是無關聯的。比如張三在一個網站上有多次訪問請求,李四也在這個網站上有多次訪問請求,他們的請求順序與時間是無規則的。那麼網站服務器是不知道到底哪些是張三的請求,哪些是李四的請求。如果在他們請求時服務器都有一個固定的標籤跟蹤,就能分辨了。這個標籤就可以看做是session.

2、為什麼要會話保持?

答: 因為負載均衡集群會將同一個用戶的請求通過算法調度給多臺服務器,變成了一對多的局面。就好像我要給父母打電話,父母原來使用同一個電話變成了父母各使用一個電話,我說的話,被一半一半的調度給父母各自持有的電話上。那麼最終的結果就是父母各聽了一半,根本不知道我要說什麼。

所以負載均衡和會話保持是矛盾的,但又必須得共存。

二、會話保持的幾個方案:

1、nginx的ip_hash算法

實現原理就是同一個客戶端的所有請求只調度給同一個後臺tomcat,這樣會話就能保持在同一臺服務器上。

注:其它的負載均衡軟件也有類似算法:如LVS的sh算法,haproxy的source算法等。

優點:配置最簡單,在nginx的upstream調度里加一句ip_hash即可

缺點:後端tomcat宕機,用戶session會丟失

2、tomcat的session複製集群

多臺tomcat通過組播互相溝通會話信息,以保持不同tomcat之間的會話一致性。

優點:後端tomcat宕機,用戶session不丟失

缺點:使用組播將信息複製到多個tomcat節點,網絡開銷大

3、緩存集中式管理session

session可以保存在文件,數據庫和內存中,利用memcached或redis將session信息緩存,以達到會話信息不丟失,也不影響負載均衡的目的。

優點:只要緩存服務器沒問題,用戶session不會丟.也沒有額外的網絡開銷

缺點:太依賴緩存服務器;需要額外的緩存服務器,成本也高;當然要求維護人員技術水平也較高,適合於性能要求高的大型環境。

三、使用MSM實現nginx+tomcat集群的會話保持

1、MSM是什麼?

MSM(memcached-session-manager)就是緩存集中式管理session的一種方案 ,它可以把tomcat的會話信息保存在緩存服務器memcached中,實現在負載均衡調度時還能保持會話一致。

nginx+tomcat會話保持方案探討

2、實驗準備:

① 靜態ip

10.1.1.11 http://nginx.cluster.com

10.1.1.12 http://tomcat1.cluster.com

10.1.1.13 http://tomcat2.cluster.com

10.1.1.14 http://memcached.cluster.com

② 主機名綁定

③ 關閉防火牆和Selinux

④ 時間同步

⑤ yum源(centos7安裝完系統後的默認yum源就OK)

3、實驗過程

第1步: 在所有tomcat節點上安裝

首先在官網下載二進制版tomcat

下載地址: https://tomcat.apache.org/download-90.cgi

在centos7上確認openjdk已經安裝

# java -version

openjdk version "1.8.0_161"

OpenJDK Runtime Environment (build 1.8.0_161-b14)

OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)

直接解壓下載好的二進制版tomcat安裝並啟動

# tar xf /root/Desktop/apache-tomcat-9.0.14.tar.gz -C /usr/local/

# mv /usr/local/apache-tomcat-9.0.14/ /usr/local/tomcat

# /usr/local/tomcat/bin/startup.sh

第2步:在所有tomcat節點(tomcat1和tomcat2)的家目錄裡創建一個顯示session信息的代碼文件

注:文件內容是一模一樣的

[root@tomcat1 ~]# vim /usr/local/tomcat/webapps/ROOT/session.jsp

SessionID:

SessionIP:

SessionPort:

[root@tomcat2 ~]# vim /usr/local/tomcat/webapps/ROOT/session.jsp

SessionID:

SessionIP:

SessionPort:

第3步: 安裝並配置nginx配置文件,實現nginx+tomcat的動靜分離與負載均衡。

[root@nginx ~]# yum install epel-release -y

[root@nginx ~]# yum install nginx -y

[root@nginx ~]# vim /etc/nginx/nginx.conf

將下面一段加到http {}配置段裡但是不要在server {}配置段裡

upstream tomcat {

server 10.1.1.12:8080 weight=1;

server 10.1.1.13:8080 weight=1;

}

把server {}配置段裡下面一段修改

location / {

}

修改成

location ~ .*\.jsp$ {

proxy_pass http://tomcat;

proxy_set_header Host $host;

proxy_set_header X-Forwarded-For $remote_addr;

}

最終結果如下圖所示:

nginx+tomcat會話保持方案探討

第4步:啟動nginx服務

[root@vm1 ~]# systemctl restart nginx

[root@vm1 ~]# systemctl enable nginx

第5步: 下載MSM相關的jar包,並拷貝到所有tomcat節點的/usr/local/tomcat/lib/目錄下

nginx+tomcat會話保持方案探討

nginx+tomcat會話保持方案探討

nginx+tomcat會話保持方案探討

第6步: 確認jar包都拷貝完成後,配置所有tomcat節點(tomcat1和tomcat2都一樣配置)

把下面一段加到context.xml配置文件最後一行前面; 也就是<context> /<context>標籤中間;10.1.1.14為memcached服務器IP

# vim /usr/local/tomcat/conf/context.xml

<manager>

memcachedNodes="n1:10.1.1.14:11211"

lockingMode="auto"

sticky="false"

requestUriIgnorePattern= ".*\.(png|gif|jpg|css|js)$"

sessionBackupAsync= "false"

sessionBackupTimeout= "100"

copyCollectionsForSerialization="true"

transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" />

nginx+tomcat會話保持方案探討

第7步: 所有tomcat節點重啟tomcat服務

# /usr/local/tomcat/bin/shutdown.sh

# /usr/local/tomcat/bin/startup.sh

第8步: 在memcached服務器上安裝,並啟動服務

[root@vm4 ~]# yum install memcached -y

[root@vm4 ~]# systemctl restart memcached

[root@vm4 ~]# systemctl enable memcached

[root@vm4 ~]# lsof -i:11211

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

memcached 4224 memcached 26u IPv4 44869 0t0 TCP *:memcache (LISTEN)

memcached 4224 memcached 27u IPv6 44870 0t0 TCP *:memcache (LISTEN)

memcached 4224 memcached 28u IPv4 44873 0t0 UDP *:memcache

memcached 4224 memcached 29u IPv6 44874 0t0 UDP *:memcache

第9步: 使用瀏覽器訪問測試

nginx+tomcat會話保持方案探討

至此,會話保持就成功了。

/<manager>


分享到:


相關文章: