首頁 後端開發 php教程 解決nginx負載平衡的session共享問題

解決nginx負載平衡的session共享問題

Jul 29, 2016 am 09:15 AM
cookie memcache mysql nginx session

查了一些資料,看了一些別人寫的文檔,總結如下,實現nginx session的共享

PHP伺服器有多台,用nginx做負載均衡,這樣同一個IP訪問同一個頁面會被分配到不同的伺服器上,如果session不同步的話,就會出現很多問題,比如說最常見的登入狀態,下面提供了幾種方式來解決session共享的問題:

1、不使用session,換用cookie

session是存放在伺服器端的,cookie是存放在客戶端的,我們可以把使用者存取頁面產生的session放到cookie裡面,就是以cookie為中轉站。你訪問web伺服器A,產生了session然後把它放到cookie裡面,當你的請求被分配到B伺服器時,伺服器B先判斷伺服器有沒有這個session,如果沒有,再去看看客戶端的cookie裡面有沒有這個session,如果也沒有,表示session真的不存,如果cookie裡面有,就把cookie裡面的sessoin同步到伺服器B,這樣就可以實現session的同步了。

說明:這種方法實現起來簡單,方便,也不會加大資料庫的負擔,但是如果客戶端把cookie禁掉了的話,那麼session就無從同步了,這樣會給網站帶來損失;cookie的安全性不高,雖然它已經加了密,但還是可以偽造的。

2、session存在資料庫(MySQL等)中

PHP可以設定將session保存在資料庫中,這種方法是把存放session的表和其他資料庫表放在一起,如果mysql也做了叢集了話,每個mysql節點都要有這張表,而且這張session表的資料表要即時同步。

說明:用資料庫來同步session,會增加資料庫的IO,增加資料庫的負擔。而且資料庫讀寫速度較慢,不利於session的適時同步。

3、session存在memcache或redis中

memcache可以做分佈式,php設定檔中設定儲存方式為memcache,這樣php自己就會建立一個session集群,將session資料儲存在memcache中。

說明:以這種方式來同步session,不會加大資料庫的負擔,並且安全性比用cookie大大的提高,把session放到記憶體裡面,比從檔案中讀取要快很多。但是memcache把記憶體分成很多種規格的儲存塊,有塊就有大小,這種方式也就決定了,memcache不能完全利用內存,會產生內存碎片,如果存儲塊不足,還會產生內存溢出。

4、nginx中的ip_hash技術能夠將某個ip的請求定向到同一台後端,這樣一來這個ip下的某個客戶端和某個後端就能建立起穩固的session,ip_hash是在upstream設定中定義的:

  1. stream nginx.example.com  
  2.     {   8.74.235:80;   
  3.              server 192.168.74.236:80   server 192.168.74.236:80   server 192.168.74.236:800     ip_hash;  
  4.     }  
  5.     server  
  6.     {  
  7.              listen 80;  
  8.              location /  
  9.              {  
  10.                      proxy_pass  
  11.                     http://nginx.example.com ;  
  12.              }  
  13.  }  
  14.  }  
  15. _ipkip在一些情況下使用:
  16. 1 .nginx不是最前端的伺服器。 ip_hash要求nginx一定是最前端的伺服器,否則nginx得不到正確ip,就不能根據ip作hash。譬如使用的是squid為最前端,那麼nginx取ip時只能得到squid的伺服器ip位址,用這個位址來做分流是肯定錯亂的。
  17. 2.nginx的後端還有其它方式的負載平衡。

假如nginx後端又有其它負載平衡,將請求又透過另外的方式分流了,那麼某個客戶端的請求肯定不能定位到同一台session應用伺服器上。這麼算起來,nginx後端只能直接指向應用程式伺服器,或是再搭一個squid,然後指向應用程式伺服器。最好的方法是用 location作一次分流,將需要session的部分請求通過ip_hash分流,剩下的走其它後端去。

5、upstream_hash
為了解決ip_hash的一些問題,可以使用upstream_hash這個第三方模組,這個模組多數情況下是用作url_hash的,但是並不妨礙將它用來做session共享。沒試過真心的不懂

補充:memcached簡單的介紹

一、概念

Memcached是danga.com(營運LiveJournal的技術團隊)開發的一套分散式記憶體物件快取系統,用於在動態系統中減少資料庫負載,提升效能。

二、適用場合

1.      分散式應用。由於memcached本身是基於分散式的系統,因此特別適合大型的分散式系統。

2.      資料庫前段快取。資料庫常常是網站系統的瓶頸。資料庫的大並發量訪問,常常造成網站記憶體溢出。當然我們也可以使用Hibernate的快取機制。但memcached是基於分散式的,並可獨立於網站應用程式本身,所以更適合大型網站進行應用程式的分割。

3.      伺服器間資料共享。舉例來講,我們將網站的登入系統、查詢系統拆分為兩個應用,放在不同的伺服器上,並進行集群,那這個時候用戶登入後,登入資訊如何從登入系統伺服器同步到查詢系統伺服器呢?這時候,我們便可以使用memcached,登入系統將登入資訊快取起來,查詢系統便可以獲得登入信息,就像獲取本地資訊一樣。

三、不適用場合

那些不需要「分佈」的,不需要共享的,或者乾脆規模小到只有一台伺服器的應用,memcached不會帶來任何好處,相反還會拖慢系統效率,因為網路連線同樣需要資源

解決方案,使用memcached做為session的存儲,memcached伺服器設定在和nginx同一台linux主機上。

解決過程,

兩台apache的主機IP分別是192.168.74.235192.168.74.236

Nginx主機IP是192.168.74.131174.1317135332533393333個主機3413139353339393393393339333393333933339333333333333333型.

在192.168.74.131 安裝memcached,且啟動

以一台為例192.168.74.236,安裝php及php對memcached的依賴函式庫yuminstall memcached-devel.i686 libmemcached-devel.i686  php-pecl-meacheache.i6865% save_handler= memcache

session.save_path= "tcp://192.168.74.131:11211"

或(以下兩個都沒有嘗試)

1.某個目錄下的.htaches ):mccache> "

php_value session.save_path  "tcp://IP:11211"

2.在某個應用中:

ini_set("session.save_handler", "memcache");

ini_set("session.save_handler", "memcache");

ini_set("ses.save_set("ses" "tcp://IP:11211"); 

同時一定要把下面的;session.save_path= "/var/lib/php/session" 註解掉

同時把extension=memcache.so 打開

重啟一下

同時把extension=memcache.so 打開

重啟一下apache,查看phpinfo 中的"Registered save handlers" 會有"files usermemcache" 這3個可用,如果有就證明裝好了

Memcached伺服器執行及結果

[root@Git ~]# memcached-tool127.0.0

[root@Git ~]# memcached-tool127.0.0

[root@Git ~]# memcached-tool127.0.0 .1:11211

 #  Item_Size  Max_age  Pages   Count   Full? Evicted Evict_Time OOM

在236機器上加入以下的php... SESSION['TEST '])) {

   $_SESSION['TEST'] = time();

}

$_SESSION['TEST3'] = time();

print

print $_SESSION['TEST3'] = time();

print

print $_SESSION['TESTSESSION; "

";

print $_SESSION['TEST3'];

print "

";

print session_id();

?>

print session_id();

?>

然後去mcmeached執行

[root@Git ~]# memcached-tool127.0.0.1:11211

 #  Item_Size  Max_age  Pages          0s       1      0      no        寫到memcached伺服器上了。

總結下:

1.      防火牆問題,許多連接區域網路伺服器失敗都是防火牆造成的

2.      依賴沒有安裝完畢,一開始使用memcached總失敗,因為我沒有安裝的擴充內容-memcacheded

以上就介紹了解決nginx負載平衡的session共享問題,包含了方面的內容,希望對PHP教程有興趣的朋友有幫助。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

docker容器名稱怎麼查 docker容器名稱怎麼查 Apr 15, 2025 pm 12:21 PM

可以通過以下步驟查詢 Docker 容器名稱:列出所有容器(docker ps)。篩選容器列表(使用 grep 命令)。獲取容器名稱(位於 "NAMES" 列中)。

MySQL的角色:Web應用程序中的數據庫 MySQL的角色:Web應用程序中的數據庫 Apr 17, 2025 am 12:23 AM

MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

docker怎麼啟動mysql docker怎麼啟動mysql Apr 15, 2025 pm 12:09 PM

在 Docker 中啟動 MySQL 的過程包含以下步驟:拉取 MySQL 鏡像創建並啟動容器,設置根用戶密碼並映射端口驗證連接創建數據庫和用戶授予對數據庫的所有權限

laravel入門實例 laravel入門實例 Apr 18, 2025 pm 12:45 PM

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

docker怎麼啟動容器 docker怎麼啟動容器 Apr 15, 2025 pm 12:27 PM

Docker 容器啟動步驟:拉取容器鏡像:運行 "docker pull [鏡像名稱]"。創建容器:使用 "docker create [選項] [鏡像名稱] [命令和參數]"。啟動容器:執行 "docker start [容器名稱或 ID]"。檢查容器狀態:通過 "docker ps" 驗證容器是否正在運行。

docker怎麼創建容器 docker怎麼創建容器 Apr 15, 2025 pm 12:18 PM

在 Docker 中創建容器: 1. 拉取鏡像: docker pull [鏡像名] 2. 創建容器: docker run [選項] [鏡像名] [命令] 3. 啟動容器: docker start [容器名]

解決數據庫連接問題:使用minii/db庫的實際案例 解決數據庫連接問題:使用minii/db庫的實際案例 Apr 18, 2025 am 07:09 AM

在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

centos7如何安裝mysql centos7如何安裝mysql Apr 14, 2025 pm 08:30 PM

優雅安裝 MySQL 的關鍵在於添加 MySQL 官方倉庫。具體步驟如下:下載 MySQL 官方 GPG 密鑰,防止釣魚攻擊。添加 MySQL 倉庫文件:rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm更新 yum 倉庫緩存:yum update安裝 MySQL:yum install mysql-server啟動 MySQL 服務:systemctl start mysqld設置開機自啟動

See all articles