本文介绍下,php结合memcache实现多服务器共享session的例子,深入学习下memcache的用法,有需要的朋友参考下。 基于文件的Session存取瓶颈都是在磁盘IO操作上,对付小数据量的Session没有问题…,

本文介绍下,php结合memcache实现多服务器共享session的例子,深入学习下memcache的用法,有需要的朋友参考下。

基于文件的Session存取瓶颈都是在磁盘IO操作上,对付小数据量的Session没有问题。
碰到大数据量的Sesstion,最好还是利用Memcache或redis来保存Session数据,直接通过内存的方式,效率会高很多。

首先,打开php.ini文件,找到session的部分:(分号后面为注释)
 

[Session]
; Handler used to store/retrieve data.
session.save_handler = files ; 这个是session的方式,默认的files即可,表示用文件储存。

还有两种方式,user和memcache。
user方式指的是自己(也就是用户)定义session的句柄,用于session的存取等,这个可以把session扩展存到数据库里。
memcache方式,需要配置好memcache,还要配置session.save_path。

使用memcache来作PHP 的session.save_handler:
 

ini_set("session.save_handler", "memcache");  
ini_set("session.save_path", "tcp://127.0.0.1:11211,tcp://192.168.1.12:11211");

使用memcached 来作PHP 的session.save_handler:
 

ini_set("session.save_handler","memcached");  
ini_set("session.save_path","127.0.0.1:11211");

下面介绍,PHP实现多服务器session共享之memcache共享的方法。
例子:
自定义session处理机制。
 

<?php  
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */  
//===========================================  
// 程序:   Memcache-Based Session Class  
// 功能:   基于Memcache存储的 Session 功能类  
//===========================================  
  
/** 
 * 文件:    MemcacheSession.inc.php 
 * 类名:    MemcacheSession Class 
 * 功能:    自主实现基于Memcache存储的 Session 功能 
 * 描述:    这个类就是实现Session的功能,基本上是通过 
 *          设置客户端的Cookie来保存SessionID, 
 *          然后把用户的数据保存在服务器端,最后通过 
 *          Cookie中的Session Id来确定一个数据是否是用户的, 
 *          然后进行相应的数据操作 
 * 
 *          本方式适合Memcache内存方式存储Session数据的方式, 
 *          同时如果构建分布式的Memcache服务器, 
 *          能够保存相当多缓存数据,并且适合用户量比较多并发比较大的情况 
 * 
 * 注意: 本类必须要求PHP安装了Memcache扩展或者必须有Memcache的PHP API 
 *       获取Memcache扩展请访问: http://pecl.php.net 
 */  
  
//设定 SESSION 有效时间,单位是 秒  
define('SESS_LIFTTIME', 3600);  
  
//定义memcache配置信息  
define('MEMCACHE_HOST', 'localhost');  
define('MEMCACHE_PORT', '10000');  
  
if (!defined('MemcacheSession'))  
{  
    define('MemcacheSession',    TRUE);  
    class MemacheSession  
    {  
        // {{{ 类成员属性定义  
        static  $mSessSavePath;  
        static  $mSessName;  
        static  $mMemcacheObj;  
        // }}}  
  
        // {{{ 初始化构造函数  
        /** 
     * 构造函数 
     * 
     * @param string $login_user    登录用户 
     * @param int $login_type       用户类型 
     * @param string $login_sess    登录Session值 
     * @return Esession 
     */  
        public function __construct()  
        {  
            //我的memcache是以php模块的方式编译进去的,可以直接调用  
            //如果没有,就请自己包含 Memcache-client.php 文件  
            if (!class_exists('Memcache') || !function_exists('memcache_connect'))  
            {  
                die('Fatal Error:Can not load Memcache extension!');  
            }  
  
            if (!empty(self::$mMemcacheObj) && is_object(self::$mMemcacheObj))  
            {  
                return false;  
            }  
  
            self::$mMemcacheObj = new Memcache;  
  
            if (!self::$mMemcacheObj->connect(MEMCACHE_HOST , MEMCACHE_PORT))  
            {  
                die('Fatal Error: Can not connect to memcache host '. MEMCACHE_HOST .':'. MEMCACHE_PORT);  
            }  
  
            return TRUE;  
        }  
        // }}}  
  
    /** {{{ sessOpen($pSavePath, $name) 
     * 
     * @param   String  $pSavePath 
     * @param   String  $pSessName 
     * 
     * @return  Bool    TRUE/FALSE 
     */  
        public function sessOpen($pSavePath = '', $pSessName = '')  
        {  
            self::$mSessSavePath    = $pSavePath;  
            self::$mSessName        = $pSessName;  
            return TRUE;  
        }  
        // }}}  
  
    /** {{{ sessClose() 
     * 
     * @param   NULL 
     * 
     * @return  Bool    TRUE/FALSE 
     */  
        public function sessClose()  
        {  
            return TRUE;  
        }  
        // }}}  
  
    /** {{{ sessRead($wSessId) 
     * 
     * @param   String  $wSessId 
     * 
     * @return  Bool    TRUE/FALSE 
     */  
        public function sessRead($wSessId = '')  
        {  
            $wData = self::$mMemcacheObj->get($wSessId);  
  
            //先读数据,如果没有,就初始化一个  
            if (!empty($wData))  
            {  
                return $wData;  
            }  
            else  
            {  
                //初始化一条空记录  
                $ret = self::$mMemcacheObj->set($wSessId, '', 0, SESS_LIFTTIME);  
                if (TRUE != $ret)  
                {  
                    die("Fatal Error: Session ID $wSessId init failed!");  
                    return FALSE;  
                }  
                return TRUE;  
            }  
        }  
        // }}}  
  
        /** {{{ sessWrite($wSessId, $wData) 
     * 
     * @param   String  $wSessId 
     * @param   String  $wData 
     * 
     * @return  Bool    TRUE/FALSE 
     */  
        public function sessWrite($wSessId = '', $wData = '')  
        {  
            $ret = self::$mMemcacheObj->replace($wSessId, $wData, 0, SESS_LIFTTIME);  
            if (TRUE != $ret)  
            {  
                die("Fatal Error: SessionID $wSessId Save data failed!");  
                return FALSE;  
            }  
            return TRUE;  
        }  
        // }}}  
  
    /** {{{ sessDestroy($wSessId) 
     * 
     * @param   String  $wSessId 
     * 
     * @return  Bool    TRUE/FALSE 
     */  
        public function sessDestroy($wSessId = '')  
        {  
            self::sessWrite($wSessId);  
            return FALSE;  
        }  
        // }}}  
  
    /** {{{ sessGc() 
     * 
     * @param   NULL 
     * 
     * @return  Bool    TRUE/FALSE 
     */  
        public function sessGc()  
        {  
            //无需额外回收,memcache有自己的过期回收机制  
            return TRUE;  
        }  
        // }}}  
  
    /** {{{ initSess() 
     * 
     * @param   NULL 
     * 
     * @return  Bool    TRUE/FALSE 
     */  
        public function initSess()  
        {  
            //不使用 GET/POST 变量方式  
            ini_set('session.use_trans_sid',    0);  
  
            //设置垃圾回收最大生存时间  
            ini_set('session.gc_maxlifetime',   SESS_LIFTTIME);  
  
            //使用 COOKIE 保存 SESSION ID 的方式  
            ini_set('session.use_cookies',      1);  
            ini_set('session.cookie_path',      '/');  
              
            $domain = '.imysql.cn';  
            //多主机共享保存 SESSION ID 的 COOKIE  
            ini_set('session.cookie_domain',    $domain);  
  
            //将 session.save_handler 设置为 user,而不是默认的 files  
            session_module_name('user');  
  
            //定义 SESSION 各项操作所对应的方法名:  
            session_set_save_handler(  
                array('MemacheSession', 'sessOpen'),   //对应于静态方法 My_Sess::open(),下同。  
                array('MemacheSession', 'sessClose'),  
                array('MemacheSession', 'sessRead'),  
                array('MemacheSession', 'sessWrite'),  
                array('MemacheSession', 'sessDestroy'),  
                array('MemacheSession', 'sessGc')  
            );  
  
            session_start();  
            return TRUE;  
        }  
        // }}}  
    }//end class  
}//end define  
  
$memSess    = new MemacheSession;  
$memSess->initSess();  
?>

在程序中的头文件中直接包含 MemacheSession.inc.php 即可使用该类。

测试实例。
1,创建一个session
 

<?php  
//set_session.php  
session_start();  
if (!isset($_SESSION['admin'])) {  
    $_SESSION['TEST'] = 'wan';  
}  
print $_SESSION['admin'];  
print "/n";  
print session_id();  
?>

2,用sessionid到memcached中查询:
 

<?php  
//get_session.php  
$mem = new Memcache;  
$mem->connect("127.0.0.1", 11211);  
var_dump($mem->get('0935216dbc0d721d629f89efb89affa6'));  
?>

备注:memcache PECL 未来版本中,可以直接设置 php.ini设定session.save_handler。

比如:
 

session.save_handler = memcache  
session.save_path = "tcp://host:port?persistent=1&weight=2&timeout=2&retry_interval=15,tcp://host2:port2"