負載均衡時訪問頁面會把請求分發到不同的服務器,session是存在服務器端,如果首次訪問被分發到A服務器,那麼session就會被存到A服務器,再次訪問時負載均衡會分發到B服務器那麼第一次訪問的session信息就會獲取不到之前的session信息。從而導致數據的不一致。
解決方案有以下幾種:
方案一(nginx或者haproxy做的負載均衡):
用Nginx 做的負載均衡可以添加ip_hash這個配置,
用haproxy做的負載均衡可以用 balance source這個配置。
從而使同一個ip的請求發到同一臺服務器。
方案二 利用數據庫同步session:
這種方案不可取,這樣會加大數據庫的訪問壓力。
方案三 利用cookie同步session數據原理圖如下:
代碼如下:
A服務器:
<?php
session_start();
if(isset($_SESSION['username'])){
echo 'ok you can go next';
}else if(isset($_COOKIE['username'])){
echo 'session is not in this server but cookie is exist';
$_SESSION['username']=$_COOKIE['username'];
}else{
echo 'cookie and session does\'t in this server';
$_SESSION['username']='lampol';
setCookie('username','lampol',time()+30*24*60*60);
}
echo '</br>';
echo 'this is A server';
echo '</br>';
var_dump($_SESSION);
B服務器:
<?php
session_start();
if(isset($_SESSION['username'])){
echo 'ok you can go next';
}else if(isset($_COOKIE['username'])){
echo 'session is not in this server but cookie is exist';
$_SESSION['username']=$_COOKIE['username'];
}else{
echo 'cookie and session does\'t in this server';
$_SESSION['username']='lampol';
setCookie('username','lampol',time()+30*24*60*60);
}
echo '</br>';
echo 'this is B server';
echo '</br>';
var_dump($_SESSION);
然後開始訪問:
第一次訪問發到B服務器 沒有session和cookie數據 然後會存到session和本地cookie
刷新第二次訪問分發到A服務器 session不存在但是cookie再本地存在 此時會把本地的cookie同步到B服務器中
缺點 如果禁用cookie那就完蛋了。
方案四 memcache或者redis存session(以memcache為例)
安裝memcache及客戶端和服務端,然後
<?php
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "192.168.1.142:11211");
//以上配置可以再php.ini中配置
session_start();
$_SESSION['username']='lampol';
這樣就把session信息存到了memache中 (redis同理)
然後在運行
<?php
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "192.168.1.142:11211");
session_start();
$mem = new Memcache;
$mem->connect('192.168.1.142',11211);
$id=session_id();
echo $mem->get($id);
本人自認為這種方案還是比較可取的。當然了到底用哪種方案,大家可以結合實際進行選擇。