nginx負載均衡session共享解決方案


解決方案:

1、使用客戶端的cookie作為存放登錄信息的媒介

cookie是將用戶登錄信息存儲在用戶終端的數據載體,與session的最大區別就是,session是存儲在服務器端的;所以這就很容易解決這種session的多台服務器共享問題。當我們客戶端進行登錄的時候,訪問的是服務器a,登錄成功之后我們將session抽取出來存放在客戶端的cookie里面;然后當我們客戶端第二次進行訪問的時候,訪問的是服務器b,這次我們先在服務器b去查找是否有登錄成功的session,如果為空,我們再對客戶端的cookie進行查找,如果cookie里面已經存儲有session,那么再將cookie里面的session同步到服務器b,那么整個流程就能走通了,用戶也不用再次登錄;

優點:這種方法實現起來簡單,方便,很容易上手操作,不會加大數據庫的負擔;

缺點:如果客戶端把cookie禁掉了的話,那么session就無法同步了,而且cookie的安全性不高,很容易外部被偽造使用;

 

2、使用mysql數據庫存儲session

既然每個服務器都需要使用同一個session,那么我們可以將session存放在同一個數據庫里面,每次訪問的時候,我們去數據庫check一下是否有這個session或者這個session是否過期,然后就可以進行多台服務器的session同步了;

優點:使用這種方法簡單、方便,很容易上手操作;

缺點:使用數據庫來同步session,會加大數據庫的IO,增加數據庫的負擔;同時,每次訪問都需要攔截請求、查詢數據庫,導致多一層訪問的業務層以及浪費讀取數據庫session時間;

 

3、使用memcache或者redis等緩存機制存放session

使用memcache或者redis等分布式緩存機制存放session數據,是現在很多大型項目負載均衡同步session的熱門方案;它的原理是項目都使用的是同一個地方的memcache或者redis的緩存,當用戶登錄的時候,會把session存放在緩存里面,之后不管訪問的是項目的那一台服務器,都會從同一個地方去獲取session緩存,這樣就很輕松實現了session同步;

優點:用緩存來同步session,不會加大數據庫的負擔,也不用手動去判斷session是否存在或過期,省去部分業務邏輯,同時,由於redis等緩存是存放於服務器端,安全性也大大提高;

缺點:memcache或redis把內存分成很多種規格的存儲塊,有塊就有大小,這種方式也就決定了,memcache或redis不能完全利用內存,會產生內存碎片,如果存儲塊不足,還會產生內存溢出。

 把php.ini里的session save handler設置為memcache 或者 redis. 推薦使用memcache 如果用redis的話,目前沒有好用的cluster解決方案,而redis還會

把數據回寫到硬盤上,完全沒必要。而memcache只需要很少的配置就能做cluster

 

4、ip_hash

nginx中的ip_hash技術能夠將某個ip的請求固定到同一台后端應用服務器,這樣一來這個ip下的某個客戶端和某個后端就能建立起穩固的session,ip_hash是在upstream配置中定義的:

  

 
upstream backend {
 
    server 127.0.0.1:8001;
 
    server 127.0.0.1:8002;
 
    ip_hash;
 
}

 

優點:ip_hash算法可以把一個ip映射到一台服務器上,這樣可以解決session同步的問題。這樣每個訪客固定訪問一個后端服務器,可以解決session的問題;

缺點:使用ip_hash進行session共享,它的原理是為每個訪問者提供一個固定的訪問ip,讓用戶只能在當前訪問的服務器上進行操作,保持了session同步的,但是也造成了負載不均衡的問題,如果當前用戶訪問的服務器掛了的話,那就會出現問題了;

 說明:因為這種方式只能用IP來分配后端,所以要求nginx一定要是最前端的服務器,否則nginx會取不到真實的客戶端ip,那ip_hash就失效了。例如在服務器架構中使用squid做前端高速緩存,那么nginx取到的就是squid服務器的ip,用這個ip來做ip_hash肯定是不對的。再有,如果nginx的后端還有其他的負載均衡,將請求又分流了,那么對於某個客戶端的請求,肯定不能定位到同一台應用服務器(例如php的fast-cgi服務器等),這樣也不能做到session共享,如果在nginx后面再做負載均衡,我們可以再搭一台squid,然后再直接到應用服務器,或者用 location作一次分流,將需要session的部分請求通過ip_hash分流,剩下的走其它后端

 

5、upstream_hash

upstream_hash 是nginx 的一個第三方模塊,支持采用nginx 內部的各種變量作hash,然后針對生成的hash 值,用求余的方式分布到后端(backend)服務器上,達到負載均衡的目的。該模塊一般情況下是用做url_hash的,但是也可以做session共享。

假如前端是squid,他會將ip加入x_forwarded_for這個http_header里,用upstream_hash可以用這個頭做因子,將請求定向到指定的后端:

可見這篇文檔:

鏈接地址

在文檔中是使用$request_uri做因子,稍微改一下:

hash $http_x_forwarded_for;

這樣就改成了利用x_forwarded_for這個頭作因子,在nginx新版本中可支持讀取cookie值,所以也可以改成:

hash $cookie_jsessionid;

假如在php中配置的session為無cookie方式,配合nginx自己的一個userid_module模塊就可以用nginx自發一個cookie,可參見userid模塊的英文文檔:

鏈接地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM