Nginx 連接tomcat時會話粘性問題分析及解決方法
在多臺后臺服務器的環(huán)境下,我們?yōu)榱舜_保一個客戶只和一臺服務器通信,我們勢必使用長連接。使用什么方式來實現(xiàn)這種連接呢,常見的有使用nginx自帶的ip_hash來做,我想這絕對不是一個好的辦法,如果前端是CDN,或者說一個局域網(wǎng)的客戶同時訪問服務器,導致出現(xiàn)服務器分配不均衡,以及不能保證每次訪問都粘滯在同一臺服務器。如果基于cookie會是一種什么情形,想想看, 每臺電腦都會有不同的cookie,在保持長連接的同時還保證了服務器的壓力均衡。
問題分析:
1. 一開始請求過來,沒有帶session信息,jvm_route就根據(jù)round robin的方法,發(fā)到一臺tomcat上面。
2. tomcat添加上session 信息,并返回給客戶。
3. 用戶再此請求,jvm_route看到session中有后端服務器的名稱,它就把請求轉(zhuǎn)到對應的服務器上。
暫時jvm_route模塊還不支持默認fair的模式。jvm_route的工作模式和fair是沖突的。對于某個特定用戶,當一直為他服務的 tomcat宕機后,默認情況下它會重試max_fails的次數(shù),如果還是失敗,就重新啟用round robin的方式,而這種情況下就會導致用戶的session丟失。
總的說來,jvm_route是通過session_cookie這種方式來實現(xiàn)session粘性,將特定會話附屬到特定tomcat上,從而解決session不同步問題,但無法解決宕機后會話轉(zhuǎn)移問題。
假如沒有這個jvm_route,用戶再請求的時候,由于沒有session信息,nignx就會再次隨機的發(fā)送請求到后端的tomcat服務器,這種情況,對于普通的頁面訪問是沒有問題的。對于帶有登錄驗證信息的請求,其結(jié)果就是永遠登錄不了應用服務器。
這個模塊通過session cookie的方式來獲取session粘性。如果在cookie和url中并沒有session,則這只是個簡單的round-robin 負載均衡。
要解決以上類似的問題,從網(wǎng)上查了下,大致有如下幾種方式:
1)ip_hash(不推薦使用)
nginx中的ip_hash技術(shù)能夠?qū)⒛硞€ip的請求定向到同一臺后端,這樣一來這個ip下的某個客戶端和某個后端就能建立起穩(wěn)固的session,ip_hash是在upstream配置中定義的:
upstream backend {
server 192.168.12.10:8080 ;
server 192.168.12.11:9090 ;
ip_hash;
}
不推薦使用的原因如下:
1/ nginx不是最前端的服務器。
ip_hash要求nginx一定是最前端的服務器,否則nginx得不到正確ip,就不能根據(jù)ip作hash。譬如使用的是squid為最前端,那么nginx取ip時只能得到squid的服務器ip地址,用這個地址來作分流是肯定錯亂的。
2/ nginx的后端還有其它方式的負載均衡。
假如nginx后端又有其它負載均衡,將請求又通過另外的方式分流了,那么某個客戶端的請求肯定不能定位到同一臺session應用服務器上。
3/ 多個外網(wǎng)出口。
很多公司上網(wǎng)有多個出口,多個ip地址,用戶訪問互聯(lián)網(wǎng)時候自動切換ip。而且這種情況不在少數(shù)。使用 ip_hash 的話對這種情況的用戶無效,無法將某個用戶綁定在固定的tomcat上 。
2)nginx_upstream_jvm_route(nginx擴展,推薦使用) ——我試了下1.8版本的,發(fā)現(xiàn)新的版本已經(jīng)不支持了!??!擦。。不過1.4.2的版本據(jù)說是支持的。
nginx_upstream_jvm_route 是一個nginx的擴展模塊,用來實現(xiàn)基于 Cookie 的 Session Sticky 的功能。
簡單來說,它是基于cookie中的JSESSIONID來決定將請求發(fā)送給后端的哪個server,nginx_upstream_jvm_route會在用戶第一次請求后端server時,將響應的server標識綁定到cookie中的JSESSIONID中,從而當用戶發(fā)起下一次請求時,nginx會根據(jù)JSESSIONID來決定由哪個后端server來處理。
1/ nginx_upstream_jvm_route安裝
下載地址(svn):http://nginx-upstream-jvm-route.googlecode.com/svn/trunk/
假設(shè)nginx_upstream_jvm_route下載后的路徑為/usr/local/nginx_upstream_jvm_route,
(1)進入nginx源碼路徑
patch -p0 < /usr/local/nginx_upstream_jvm_route/jvm_route.patch
(2)./configure --with-http_stub_status_module --with-http_ssl_module --prefix=/usr/local/nginx --with-
pcre=/usr/local/pcre-8.33 --add-module=/usr/local/nginx_upstream_jvm_route
(3)make & make install
2/ nginx配置
upstream tomcats_jvm_route
{
# ip_hash;
server 192.168.33.10:8090 srun_id=tomcat01;
server 192.168.33.11:8090 srun_id=tomcat02;
jvm_route $cookie_JSESSIONID|sessionid reverse;
}
3/ tomcat配置
修改192.168.33.10:8090tomcat的server.xml,
將
<Engine name="Catalina" defaultHost="localhost" >
修改為:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat01">
同理,在192.168.33.11:8090server.xml中增加jvmRoute="tomcat02"。
4/ 測試
啟動tomcat和nginx,訪問nginx代理,使用Google瀏覽器,F(xiàn)12,查看cookie中的JSESSIONID,
形如:ABCD123456OIUH897SDFSDF.tomcat01 ,刷新也不會變化
3)基于cookie的Nginx Sticky模塊
總結(jié)
以上所述是小編給大家介紹的Nginx 連接tomcat時會話粘性問題分析及解決方法,希望對大家有所幫助,如果大家有 任何疑問歡迎給我留言,小編會及時回復大家的!
相關(guān)文章
nginx如何將http訪問的網(wǎng)站改成https訪問
這篇文章主要介紹了nginx如何將http訪問的網(wǎng)站改成https訪問,幫助大家更好的理解和使用nginx,感興趣的朋友可以了解下2021-02-02
nginx proxy_pass反向代理配置中url后加不加/的區(qū)別介紹
這篇文章主要給大家介紹了關(guān)于nginx proxy_pass反向代理配置中url后加不加/的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。2017-11-11
Windows下使用Nginx+Tomcat做負載均衡的完整步驟
這篇文章主要介紹了Windows下使用Nginx+Tomcat做負載均衡的完整步驟,幫助大家搭建負載均衡集群,感興趣的朋友可以了解下2020-09-09
解決nginx:[emerg]?getpwnam(“nginx“)failed報錯問題
編譯安裝nginx時,啟動服務報錯nginx:[emerg]getpwnam("nginx")failed,原因是沒有為nginx創(chuàng)建用戶,解決方法是創(chuàng)建一個nginx用戶,該用戶是你在編譯時指定的用戶2025-02-02
為高負載網(wǎng)絡(luò)優(yōu)化Nginx和Node.js的方法
如果不先對Nginx和Node.js的底層傳輸機制有所了解,并進行針對性優(yōu)化,可能對兩者再細致的調(diào)優(yōu)也會徒勞無功。一般情況下,Nginx通過TCP socket來連接客戶端與上游應用2013-02-02

