nginx负载均衡的session共享问题的解决方法
查了一些資料,看了一些別人寫的文檔,總結(jié)如下,實(shí)現(xiàn)nginx session的共享
PHP服務(wù)器有多臺(tái),用nginx做負(fù)載均衡,這樣同一個(gè)IP訪問同一個(gè)頁面會(huì)被分配到不同的服務(wù)器上,如果session不同步的話,就會(huì)出現(xiàn)很多問題,比如說最常見的登錄狀態(tài),下面提供了幾種方式來解決session共享的問題:
1、不使用session,換用cookie
session是存放在服務(wù)器端的,cookie是存放在客戶端的,我們可以把用戶訪問頁面產(chǎn)生的session放到cookie里面,就是以cookie為中轉(zhuǎn)站。你訪問web服務(wù)器A,產(chǎn)生了session然后把它放到cookie里面,當(dāng)你的請(qǐng)求被分配到B服務(wù)器時(shí),服務(wù)器B先判斷服務(wù)器有沒有這個(gè)session,如果沒有,再去看看客戶端的cookie里面有沒有這個(gè)session,如果也沒有,說明session真的不存,如果cookie里面有,就把cookie里面的sessoin同步到服務(wù)器B,這樣就可以實(shí)現(xiàn)session的同步了。
說明:這種方法實(shí)現(xiàn)起來簡單,方便,也不會(huì)加大數(shù)據(jù)庫的負(fù)擔(dān),但是如果客戶端把cookie禁掉了的話,那么session就無從同步了,這樣會(huì)給網(wǎng)站帶來損失;cookie的安全性不高,雖然它已經(jīng)加了密,但是還是可以偽造的。
2、session存在數(shù)據(jù)庫(MySQL等)中
PHP可以配置將session保存在數(shù)據(jù)庫中,這種方法是把存放session的表和其他數(shù)據(jù)庫表放在一起,如果mysql也做了集群了話,每個(gè)mysql節(jié)點(diǎn)都要有這張表,并且這張session表的數(shù)據(jù)表要實(shí)時(shí)同步。
說明:用數(shù)據(jù)庫來同步session,會(huì)加大數(shù)據(jù)庫的IO,增加數(shù)據(jù)庫的負(fù)擔(dān)。而且數(shù)據(jù)庫讀寫速度較慢,不利于session的適時(shí)同步。
3、session存在memcache或者redis中
memcache可以做分布式,php配置文件中設(shè)置存儲(chǔ)方式為memcache,這樣php自己會(huì)建立一個(gè)session集群,將session數(shù)據(jù)存儲(chǔ)在memcache中。
說明:以這種方式來同步session,不會(huì)加大數(shù)據(jù)庫的負(fù)擔(dān),并且安全性比用cookie大大的提高,把session放到內(nèi)存里面,比從文件中讀取要快很多。但是memcache把內(nèi)存分成很多種規(guī)格的存儲(chǔ)塊,有塊就有大小,這種方式也就決定了,memcache不能完全利用內(nèi)存,會(huì)產(chǎn)生內(nèi)存碎片,如果存儲(chǔ)塊不足,還會(huì)產(chǎn)生內(nèi)存溢出。
4、nginx中的ip_hash技術(shù)能夠?qū)⒛硞€(gè)ip的請(qǐng)求定向到同一臺(tái)后端,這樣一來這個(gè)ip下的某個(gè)客戶端和某個(gè)后端就能建立起穩(wěn)固的session,ip_hash是在upstream配置中定義的:
[html] view plain copy?
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是容易理解的,但是因?yàn)閮H僅能用ip這個(gè)因子來分配后端,因此ip_hash是有缺陷的,不能在一些情況下使用:
1.nginx不是最前端的服務(wù)器。
ip_hash要求nginx一定是最前端的服務(wù)器,否則nginx得不到正確ip,就不能根據(jù)ip作hash。譬如使用的是squid為最前端,那么nginx取ip時(shí)只能得到squid的服務(wù)器ip地址,用這個(gè)地址來作分流是肯定錯(cuò)亂的。
2.nginx的后端還有其它方式的負(fù)載均衡。
假如nginx后端又有其它負(fù)載均衡,將請(qǐng)求又通過另外的方式分流了,那么某個(gè)客戶端的請(qǐng)求肯定不能定位到同一臺(tái)session應(yīng)用服務(wù)器上。這么算起來,nginx后端只能直接指向應(yīng)用服務(wù)器,或者再搭一個(gè)squid,然后指向應(yīng)用服務(wù)器。最好的辦法是用 location作一次分流,將需要session的部分請(qǐng)求通過ip_hash分流,剩下的走其它后端去。
5、upstream_hash
為了解決ip_hash的一些問題,可以使用upstream_hash這個(gè)第三方模塊,這個(gè)模塊多數(shù)情況下是用作url_hash的,但是并不妨礙將它用來做session共享。沒試過真心的不明白
補(bǔ)充:memcached簡單的介紹
一、概念
Memcached是danga.com(運(yùn)營LiveJournal的技術(shù)團(tuán)隊(duì))開發(fā)的一套分布式內(nèi)存對(duì)象緩存系統(tǒng),用于在動(dòng)態(tài)系統(tǒng)中減少數(shù)據(jù)庫負(fù)載,提升性能。
二、適用場(chǎng)合
1. ? ? ?分布式應(yīng)用。由于memcached本身基于分布式的系統(tǒng),所以尤其適合大型的分布式系統(tǒng)。
2. ? ? ?數(shù)據(jù)庫前段緩存。數(shù)據(jù)庫常常是網(wǎng)站系統(tǒng)的瓶頸。數(shù)據(jù)庫的大并發(fā)量訪問,常常造成網(wǎng)站內(nèi)存溢出。當(dāng)然我們也可以使用Hibernate的緩存機(jī)制。但memcached是基于分布式的,并可獨(dú)立于網(wǎng)站應(yīng)用本身,所以更適合大型網(wǎng)站進(jìn)行應(yīng)用的拆分。
3. ? ? ?服務(wù)器間數(shù)據(jù)共享。舉例來講,我們將網(wǎng)站的登錄系統(tǒng)、查詢系統(tǒng)拆分為兩個(gè)應(yīng)用,放在不同的服務(wù)器上,并進(jìn)行集群,那這個(gè)時(shí)候用戶登錄后,登錄信息如何從登錄系統(tǒng)服務(wù)器同步到查詢系統(tǒng)服務(wù)器呢?這時(shí)候,我們便可以使用memcached,登錄系統(tǒng)將登錄信息緩存起來,查詢系統(tǒng)便可以獲得登錄信息,就像獲取本地信息一樣。
三、不適用場(chǎng)合
那些不需要“分布”的,不需要共享的,或者干脆規(guī)模小到只有一臺(tái)服務(wù)器的應(yīng)用,memcached不會(huì)帶來任何好處,相反還會(huì)拖慢系統(tǒng)效率,因?yàn)榫W(wǎng)絡(luò)連接同樣需要資源
?
解決方案,使用memcached做為session的存儲(chǔ),memcached服務(wù)器設(shè)置在和nginx同一臺(tái)linux主機(jī)上。
解決過程,
兩臺(tái)apache的主機(jī)IP分別是 192.168.74.235192.168.74.236
Nginx主機(jī)IP是192.168.74.131
Memcached主機(jī)的IP是192.168.74.131
在192.168.74.131 安裝memcached,并且啟動(dòng)
以一臺(tái)為例192.168.74.236,安裝php及php對(duì)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"
或者(以下兩個(gè)沒有嘗試)
1.某個(gè)目錄下的 .htaccess :
php_value session.save_handler "memcache"
php_value session.save_path ?"tcp://IP:11211"
2.在某個(gè)一個(gè)應(yīng)用中:
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://IP:11211");?
?
同時(shí)一定要把下面的;session.save_path= "/var/lib/php/session" 注釋掉
同時(shí)把extension=memcache.so 打開
重啟一下 apache,查看 phpinfo 中的 "Registered save handlers" 會(huì)有 "files usermemcache" 這3個(gè)可用,如果有就證明裝好了
Memcached服務(wù)器執(zhí)行及結(jié)果
[root@Git ~]# memcached-tool127.0.0.1:11211
?# ?Item_Size ?Max_age ?Pages ? Count ? Full? Evicted Evict_Time OOM
在236機(jī)器上添加下面的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服務(wù)器上執(zhí)行
[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
這樣應(yīng)該就算可以把session寫到memcached服務(wù)器上了。
總結(jié)下:
1. ? ? ?防火墻問題,很多連接局域網(wǎng)服務(wù)器失敗都是防火墻引起的
2. ? ? ?依賴沒有安裝完畢,一開始使用memcached總失敗,因?yàn)槲覜]有安裝php-memcached這樣的擴(kuò)展庫
轉(zhuǎn)載于:https://blog.51cto.com/casparcc/1742922
總結(jié)
以上是生活随笔為你收集整理的nginx负载均衡的session共享问题的解决方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Elasticsearch in Ac
- 下一篇: 巧用shell+rsync服务实现日志自