查了一些資料,看了一些別人寫的文檔,總結以下,實現nginx session的共享:php
PHP服務器有多臺,用nginx作負載均衡,這樣同一個IP訪問同一個頁面會被分配到不一樣的服務器上,若是session不一樣步的話,就會出現不少問題,好比說最多見的登陸狀態,下面提供了幾種方式來解決session共享的問題:前端
session是存放在服務器端的,cookie是存放在客戶端的,咱們能夠把用戶訪問頁面產生的session放到cookie裏面,就是以cookie爲中轉站。你訪問web服務器A,產生了session而後把它放到cookie裏面,當你的請求被分配到B服務器時,服務器B先判斷服務器有沒有這個session,若是沒有,再去看看客戶端的cookie裏面有沒有這個session,若是也沒有,說明session真的不存,若是cookie裏面有,就把cookie裏面的sessoin同步到服務器B,這樣就能夠實現session的同步了。mysql
說明:這種方法實現起來簡單,方便,也不會加大數據庫的負擔,可是若是客戶端把cookie禁掉了的話,那麼session就無從同步了,這樣會給網站帶來損失;cookie的安全性不高,雖然它已經加了密,可是仍是能夠僞造的。
nginx
PHP能夠配置將session保存在數據庫中,這種方法是把存放session的表和其餘數據庫表放在一塊兒,若是mysql也作了集羣了話,每一個mysql節點都要有這張表,而且這張session表的數據表要實時同步。git
說明:用數據庫來同步session,會加大數據庫的IO,增長數據庫的負擔。並且數據庫讀寫速度較慢,不利於session的適時同步。
github
memcache能夠作分佈式,php配置文件中設置存儲方式爲memcache,這樣php本身會創建一個session集羣,將session數據存儲在memcache中。web
說明:以這種方式來同步session,不會加大數據庫的負擔,而且安全性比用cookie大大的提升,把session放到內存裏面,比從文件中讀取要快不少。可是memcache把內存分紅不少種規格的存儲塊,有塊就有大小,這種方式也就決定了,memcache不能徹底利用內存,會產生內存碎片,若是存儲塊不足,還會產生內存溢出。
redis
這樣一來這個ip下的某個客戶端和某個後端就能創建起穩固的session,ip_hash是在upstream配置中定義的:算法
upstream nginx.example.com { server 192.168.74.235:80; server 192.168.74.236:80; ip_hash; } server { listen 80; location / { proxy_pass http://nginx.example.com; } }
ip_hash是容易理解的,可是由於僅僅能用ip這個因子來分配後端,所以ip_hash是有缺陷的,不能在一些狀況下使用:sql
1.nginx不是最前端的服務器。
ip_hash要求nginx必定是最前端的服務器,不然nginx得不到正確ip,就不能根據ip做hash。譬如使用的是squid爲最前端,那麼nginx取ip時只能獲得squid的服務器ip地址,用這個地址來做分流是確定錯亂的。
2.nginx的後端還有其它方式的負載均衡。
假如nginx後端又有其它負載均衡,將請求又經過另外的方式分流了,那麼某個客戶端的請求確定不能定位到同一臺session應用服務器上。這麼算起來,nginx後端只能直接指向應用服務器,或者再搭一個squid,而後指向應用服務器。最好的辦法是用 location做一次分流,將須要session的部分請求經過ip_hash分流,剩下的走其它後端去。
爲了解決ip_hash的一些問題,可使用upstream_hash這個第三方模塊,這個模塊多數狀況下是用做url_hash的,可是並不妨礙將它用來作session共享。(暫時不會用,不明白)
附:Nginx的ngx_http_consistent_hash模塊的官網使用文檔:https://www.nginx.com/resources/wiki/modules/consistent_hash/
Linux下該模塊的安裝編譯:
cd /usr/local/src
wget https://github.com/replay/ngx_http_consistent_hash/archive/master.zip
unzip master.zip
cd /usr/local/src/nginx-1.12.0
./configure --prefix=/usr/lcoal/nginx --add-module=/usr/local/src/ngx_http_consistent_hash-master/
pkill -9 nginx
make&make install
nginx.conf:
worker_processes 1; events { worker_connections 1024; } http { upstream servers { consistent_hash $request_uri; server 192.168.1.86:80; server 192.168.1.88:80; } server { listen 80; server_name localhost; location / { proxy_pass http://servers; } } }