我记得我之前有写过在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类和演示吧
class RedisSession{
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的前缀
**/
function RedisSession($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,"/");
}
}
/*
*设置过期时间
*参数
**/
function expire($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:值
**/
function setMutil($array){
$this->redis->hMset($this->sso_session,$array);
}
/*
*设置session的值
*参数
*$key:session的key
*$value:值
**/
function set($key,$value){
$this->redis->hSet($this->sso_session,$key,$value);
}
/*
*设置session的值为对象
*参数
*$key:session的key
*$object:对象
**/
function setObject($key,$object){
$this->redis->hSet($this->sso_session,$key,serialize($object));
}
/*
*获取全部session的key和value
@return: array
**/
function getAll(){
return $this->redis->hGetAll($this->sso_session);
}
/*
*获取一个session的key和value
@return: array
**/
function get($key){
return $this->redis->hGet($this->sso_session,$key);
}
/*
*获取session的值为对象
*参数
*$key:session的key
*$value:cookie的名字
**/
function getObject($key){
return unserialize($this->redis->hGet($this->sso_session,$key));
}
/*
*从缓存中获取一个session的key和value
@return: array
**/
function getFromCache($key){
if(!isset($this->cache)){
$this->cache=$this->getAll();
}
return $this->cache[$key];
}
/*
*删除一个session的key和value
@return: array
**/
function del($key){
return $this->redis->hDel($this->sso_session,$key);
}
/*
*删除所有session的key和value
@return: array
**/
function delAll(){
return $this->redis->delete($this->sso_session);
}
}
使用
$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();
*/