使用redis实现跨服务器session的方法

发布时间:2020-01-08编辑:脚本学堂
最近新开发了一个项目,由于使用到了4台机器做web,使用dns做负载均衡,

如上图所示,用户通过DNS的调度(一个域名对应多个ip)分别访问到VM2-VM5上,四台机器都访问VM1上

最近新开发了一个项目,由于使用到了4台机器做web,使用dns做负载均衡,
img1
如上图所示,用户通过DNS的调度(一个域名对应多个ip)分别访问到VM2-VM5上,四台机器都访问VM1上的redis,两个redis值主从结构。
因此需要使用跨服务器的session保存用户登录状态,于是便写了一个跨站的session共享的类。
 

复制代码 代码如下:
<?php
        /*
         *用redis实现跨服务器session
         *注意需要安装phpredis模块
         *
         *作者:yifangyou
         *日期:2012-07-23 22:55:00
        **/
    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.1.2";
    $redisPort="6379";
    $redis = new Redis();
    $redis->connect($redisHost,$redisPort);
    include_once("inc/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();
    */

比较常用的估计是set,get,setObject,getOject。
我用sso_session:主要是方便用phpRedisAdmin管理。
img2