我记得我之前有写过在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 需要密码验证
有没有感觉和memcached的很像,补课一下。。。
session.save_handler = memcache //设置session的储存方式为memcache
memcache.hash_strategy = "consistent"//设置memcache的hash算法
session.save_path = "tcp://127.0.0.100:11211" //设置session储存的位置,多台memcache用逗号隔开,例如:tcp://127.0.0.1:11211,tcp://127.0.0.1:12000
memcache客户端一致性hash算法
设置可以参考php官网教程
修改php.ini添加:
[Memcache]
Memcache.allow_failover = 1
Memcache.hash_strategy =consistent
Memcache.hash_function =crc32
或者ini_set方法:
Ini_set(‘memcache.hash_strategy',' consistent ');
Ini_set(‘memcache.hash_function','crc32');
重启php-fpm就OK啦~~~码完,收工,睡觉
补一个重写SESSION方案的PHP类和演示吧
<?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);
}
}
使用
<?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();
*/
版权属于: 吕滔博客
原文地址: https://lvtao.net/server/php-session-redis.html
转载时必须以链接形式注明原始出处及本声明。
[abc] |
匹配中括号中的单个字符,如a或b或c |
[^abc] |
匹配除了a、b、c等字符的其他单个字符 |
[a-z] |
匹配一个字符范围,如a到z |
[a-zA-Z] |
匹配一个字符范围,如a-z 或 A-Z |
^ |
匹配行的开始 |
$ |
匹配行的结束 |
\A |
匹配一个字符串的开始 |
\z |
匹配一个字符串的结束 |
. |
匹配任意单个字符 |
\s |
匹配空白字符,如空格,TAB |
\S |
匹配非空白字符 |
\d |
匹配一个数字 |
\D |
匹配非数字 |
\w |
匹配一个字母 |
\W |
匹配非字母 |
\b |
匹配字符边界 |
(...) |
引用所有括号中的内容 |
(a|b) |
a或者b |
a? |
零个或1个a |
a* |
零个或多个a |
a+ |
1个或多个a |
a{3} |
3次重复的a |
a{3,} |
3次或3次以上重复的a |
a{3,6} |
3到6次重复的a |
修正符 | |
/g |
查找所有可能的匹配 |
/i |
不区分大小写 |
/m |
多行匹配 |
/s |
单行匹配 |
/x |
忽略空白模式 |
/e |
可执行模式,PHP专有 |
/A |
强制从目标字符串开头匹配 |
/D |
使用$限制结尾字符,则不允许结尾有换行 |
/U |
只匹配最近的一个字符串;不重复匹配 |
全部评论:已有 7 条评论
请教一下 这个多站点 首先要得到seesionid才行 你这个seesionid存在cookie里 但是之站点cookie得不到 这个怎么解决呢
多站点好像是不能用。要改改。
好像不行啊 你这个实现不了多站点seesion共享
厉害了,我哥的!!
懂PHP的人都挺厉害的
额,毛毛雨而已啦,您这么说,,,,,这就尴尬了...
哈哈