查了一些資料,看了一些別人寫的文檔,總結以下,實現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的同步了。java
說明:這種方法實現起來簡單,方便,也不會加大數據庫的負擔,可是若是客戶端把cookie禁掉了的話,那麼session就無從同步了,這樣會給網站帶來損失;cookie的安全性不高,雖然它已經加了密,可是仍是能夠僞造的。mysql
PHP能夠配置將session保存在數據庫中,這種方法是把存放session的表和其餘數據庫表放在一塊兒,若是mysql也作了集羣了話,每一個mysql節點都要有這張表,而且這張session表的數據表要實時同步。linux
說明:用數據庫來同步session,會加大數據庫的IO,增長數據庫的負擔。並且數據庫讀寫速度較慢,不利於session的適時同步。nginx
memcache能夠作分佈式,php配置文件中設置存儲方式爲memcache,這樣php本身會創建一個session集羣,將session數據存儲在memcache中。web
說明:以這種方式來同步session,不會加大數據庫的負擔,而且安全性比用cookie大大的提升,把session放到內存裏面,比從文件中讀取要快不少。可是memcache把內存分紅不少種規格的存儲塊,有塊就有大小,這種方式也就決定了,memcache不能徹底利用內存,會產生內存碎片,若是存儲塊不足,還會產生內存溢出。redis
nginx中的ip_hash技術可以將某個ip的請求定向到同一臺後端,這樣一來這個ip下的某個客戶端和某個後端就能創建起穩固的session,ip_hash是在upstream配置中定義的:sql
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是有缺陷的,不能在一些狀況下使用:
1.nginx不是最前端的服務器。數據庫
ip_hash要求nginx必定是最前端的服務器,不然nginx得不到正確ip,就不能根據ip做hash。譬如使用的是squid爲最前端,那麼nginx取ip時只能獲得squid的服務器ip地址,用這個地址來做分流是確定錯亂的。
2.nginx的後端還有其它方式的負載均衡。
假如nginx後端又有其它負載均衡,將請求又經過另外的方式分流了,那麼某個客戶端的請求確定不能定位到同一臺session應用服務器上。這麼算起來,nginx後端只能直接指向應用服務器,或者再搭一個squid,而後指向應用服務器。最好的辦法是用 location做一次分流,將須要session的部分請求經過ip_hash分流,剩下的走其它後端去。
五、upstream_hash
爲了解決ip_hash的一些問題,可使用upstream_hash這個第三方模塊,這個模塊多數狀況下是用做url_hash的,可是並不妨礙將它用來作session共享。沒試過真心的不明白
補充:memcached簡單的介紹
1、概念
Memcached是danga.com(運營LiveJournal的技術團隊)開發的一套分佈式內存對象緩存系統,用於在動態系統中減小數據庫負載,提高性能。
2、適用場合
1. 分佈式應用。因爲memcached自己基於分佈式的系統,因此尤爲適合大型的分佈式系統。
2. 數據庫前段緩存。數據庫經常是網站系統的瓶頸。數據庫的大併發量訪問,經常形成網站內存溢出。固然咱們也可使用Hibernate的緩存機制。但memcached是基於分佈式的,並可獨立於網站應用自己,因此更適合大型網站進行應用的拆分。
3. 服務器間數據共享。舉例來說,咱們將網站的登陸系統、查詢系統拆分爲兩個應用,放在不一樣的服務器上,並進行集羣,那這個時候用戶登陸後,登陸信息如何從登陸系統服務器同步到查詢系統服務器呢?這時候,咱們即可以使用memcached,登陸系統將登陸信息緩存起來,查詢系統即可以得到登陸信息,就像獲取本地信息同樣。
3、不適用場合
那些不須要「分佈」的,不須要共享的,或者乾脆規模小到只有一臺服務器的應用,memcached不會帶來任何好處,相反還會拖慢系統效率,由於網絡鏈接一樣須要資源
解決方案,使用memcached作爲session的存儲,memcached服務器設置在和nginx同一臺linux主機上。
解決過程,
兩臺apache的主機IP分別是 192.168.74.235192.168.74.236
Nginx主機IP是192.168.74.131
Memcached主機的IP是192.168.74.131
在192.168.74.131 安裝memcached,而且啓動
以一臺爲例192.168.74.236,安裝php及php對memcached的依賴庫yuminstall memcached-devel.i686 libmemcached-devel.i686 php-pecl-memcache.i686
配置php.ini
session.save_handler= memcache
session.save_path= "tcp://192.168.74.131:11211"
或者(如下兩個沒有嘗試)
1.某個目錄下的 .htaccess :
php_value session.save_handler "memcache"
php_value session.save_path "tcp://IP:11211"
2.在某個一個應用中:
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://IP:11211");
同時必定要把下面的;session.save_path= "/var/lib/php/session" 註釋掉
同時把extension=memcache.so 打開
重啓一下 apache,查看 phpinfo 中的 "Registered save handlers" 會有 "files usermemcache" 這3個可用,若是有就證實裝好了
Memcached服務器執行及結果
[root@Git ~]# memcached-tool127.0.0.1:11211
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
在236機器上添加下面的php文件
<?php
session_start();
if (!isset($_SESSION['TEST'])) {
$_SESSION['TEST'] = time();
}
$_SESSION['TEST3'] = time();
print $_SESSION['TEST'];
print "<br><br>";
print $_SESSION['TEST3'];
print "<br><br>";
print session_id();
?>
而後去memcached服務器上執行
[root@Git ~]# memcached-tool127.0.0.1:11211
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
1 80B 0s 1 0 no 0 0 0
這樣應該就算能夠把session寫到memcached服務器上了。
總結下:
1. 防火牆問題,不少鏈接局域網服務器失敗都是防火牆引發的
2. 依賴沒有安裝完畢,一開始使用memcached總失敗,由於我沒有安裝php-memcached這樣的擴展庫