PHP叢集中SESSION共享方案之Redis
我記得我之前有寫過在PHP叢集中使用memcached來共享SESSION的解決方法,其實redis還是一樣!出差在外,咱就別太講究了,碼篇部落格做為睡前甜點吧
搭建PHP叢集的第一步就是設定負載均衡。首先我們需要三臺主機:
Nginx負載:192.166.5.111
PHP應用1:192.168.5.112
PHP應用2:192.168.5.113
大概架構如下
這兒就不介紹Nginx中的配置了,其實就是一個proxy和upstream的東東~
PHP主機之間Session共享
之前我應該是介紹過memcached共享session的方案,懶得翻了,反正原理一樣,找不找得到也無所謂,網上也有介紹用NFS共享檔案的方案,由於PHP是將session儲存在檔案中,那我們可以在Nginx負載主機上面搭建一個分散式檔案系統(NFS),讓兩臺PHP主機的session都存放在此檔案系統中。以此來達到共享session的目的。當然這都不是今天我要說的
今天想實現的是如下
加了一臺session用的redis快取伺服器192.168.5.114
PHP預設情況下是不支援對Redis的操作的。所以這裡我們需要自己手動安裝第三方的擴充套件,使其支援對Redis的操作。
在這裡我就認為我們的PHP已經支援Redis了。接下來是將session儲存到Redis中,有兩種方式:一種是直接修改PHP的配置檔案php.ini;另一種是重寫session機制。
簡單點吧,修改PHP配置檔案php.ini將session儲存到Redis中
開啟php.ini,需要修改的有這兩項:session.save_handler和session.save_path。
session.save_handler = Redis
session.save_path = “tcp://192.168.5.114:6379”
//Redis不需要密碼驗證
session.save_path = “tcp://192.168.5.114:6379?auth=password”
//Redis 需要密碼驗證
重啟php-fpm就OK啦~~~碼完,收工,睡覺
補一個重寫SESSION方案的PHP類和演示吧
<?phpclassRedisSession{
var $expire=86400;//過期時間 var $sso_session;//session id var $session_folder;//session目錄 var $cookie_name;//cookie的名字 var $redis;//redis連線 var $cache;//快取session var $expireAt;//過期時間 /*
*初始化
*引數
*$redis:php_redis的類例項
*$cookie_name:cookie的名字
*$session_id_prefix:sesion id的字首
**/functionRedisSession($redis,$expire=86400,$cookie_name="sso_session",$session_id_prefix=""){
$this->redis=$redis;
$this->cookie_name=$cookie_name;
$this->session_folder="sso_session:";
//若是cookie已經存在則以它為session的id if(isset($_COOKIE[$this->cookie_name])){
$this->sso_session=$_COOKIE[$this->cookie_name];
}else{
$this->expire=$expire;
$this->expireAt=time()+$this->expire;
//在IE6下的iframe無法獲取到cookie,於是我使用了get方式傳遞了cookie的名字 if(isset($_GET[$this->cookie_name])){
$this->sso_session=$_GET[$this->cookie_name];
}else{
$this->sso_session=$this->session_folder.$session_prefix.md5(uniqid(rand(), true));
}
setcookie($this->cookie_name,$this->sso_session,$this->expireAt,"/");
}
}
/*
*設定過期時間
*引數
**/functionexpire($expire=86400){
$this->expire=$expire;
$this->expireAt=time()+$this->expire;
//設定session過期時間
setcookie($this->cookie_name,$this->sso_session,$this->expireAt,"/",".greatwallwine.com.cn");
$this->redis->expireAt($this->sso_session, $this->expireAt);
}
/*
*設定多個session的值
*引數
*$array:值
**/functionsetMutil($array){
$this->redis->hMset($this->sso_session,$array);
}
/*
*設定session的值
*引數
*$key:session的key
*$value:值
**/functionset($key,$value){
$this->redis->hSet($this->sso_session,$key,$value);
}
/*
*設定session的值為物件
*引數
*$key:session的key
*$object:物件
**/functionsetObject($key,$object){
$this->redis->hSet($this->sso_session,$key,serialize($object));
}
/*
*獲取全部session的key和value
@return: array
**/functiongetAll(){
return$this->redis->hGetAll($this->sso_session);
}
/*
*獲取一個session的key和value
@return: array
**/functionget($key){
return$this->redis->hGet($this->sso_session,$key);
}
/*
*獲取session的值為物件
*引數
*$key:session的key
*$value:cookie的名字
**/functiongetObject($key){
return unserialize($this->redis->hGet($this->sso_session,$key));
}
/*
*從快取中獲取一個session的key和value
@return: array
**/functiongetFromCache($key){
if(!isset($this->cache)){
$this->cache=$this->getAll();
}
return$this->cache[$key];
}
/*
*刪除一個session的key和value
@return: array
**/functiondel($key){
return$this->redis->hDel($this->sso_session,$key);
}
/*
*刪除所有session的key和value
@return: array
**/functiondelAll(){
return$this->redis->delete($this->sso_session);
}
}
使用
<?php
error_reporting(0);
$redisHost="192.168.5.114";
$redisPort="6379";
$redis = new Redis();
$redis->connect($redisHost,$redisPort);
include_once("RedisSession.php");
$redisSession=new RedisSession($redis);
/*
$redisSession->set("name","sdf4");
$redisSession->set("age",1234);
$redisSession->set("***","man14");
$redisSession->set("name","abc4");
$redisSession->setMutil(array("province"=>"guangdong","city"=>"guangzhou"));
*/
$redisSession->setObject("obj",array("test1"=>array("test2")));
$obj=$redisSession->getObject("obj");
print_r($obj);
die();
print_r($redisSession->getAll());
//$redisSession->del("name");
print_r($redisSession->get("name"));
//print_r($redisSession->get("province"));
//$redisSession->delAll();
//print_r($redisSession->getAll());
print_r($redisSession->getFromCache("name"));
/*
$redisSession->del("name");
$redisSession->delAll();
*/