分布式存储Memcache替代Session方案

来源:互联网 发布:python爬虫断线重连 编辑:程序博客网 时间:2024/05/19 16:48

PHP自带的Session实际是在服务器中为每个客户建立独立的文件存放各自的信息。

在不做处理的情况下,很容易被客户端伪造。并且由于采用文件形式,所以存在着IO

读写的瓶颈。一般当用户在线达到1000左右时,就会出现访问速度明显下降的问题。

Memcache是应用层级的缓存,它将数据存储内存中。内存的访问速度是可想而知的。

PHP在使用Memcache之前,需要做两件事。

1.安装PHP的memcache扩展。

2.下载Memcache文件。

以上两步很简单,去Google一下就可以了。

下面是memcache.class.php文件中MemcacheSession类

memcache.class.php

<?phpdefine('PREFIX', 'god');define('SESS_LEFETIME', 3600);define('ZIP_FLAG', 0);class MemcacheSession {    static $Memcache;    /* 构造函数     * @param string @login_user     * @param int @login_type     * @param string $login_sess     */    public function __construct($config) {        if (!class_exists('Memcache') || !function_exists('memcache_connect')) {            exit("Can't load Memcache Extendstion");        }        $this->Memcache = new Memcache;        if (!@$this->Memcache->connect($config['host'], $config['port'])) {            exit('连接失败');        }        $this->setCookie();        return TRUE;    }    /* 增加键值     * return bool     */    public function add($key, $data='empty') {        if (!$this->Memcache->add($key, $data, ZIP_FLAG, SESS_LEFETIME)) {            exit("此键名已经被使用");        }    }    /* uniqueID     * return string     */    public function uniqueID() {        return PREFIX . md5(uniqid(rand(), true)) . $_SERVER['REMOTE_ADDR'];        ;    }    /* 读取数据     * @param string     * return string/array     */    public function get($key='') {        if ($key == '')            exit('键名不能为空');        $wData = $this->Memcache->get($key);        if (!$wData)            return FALSE;        return $wData;    }    /* 重写数据     * @param string $key     * @param string $data     * @return bool     */    public function set($key, $data='') {        $ret = $this->Memcache->set($key, $data, ZIP_FLAG, SESS_LEFETIME);        if (TRUE != $ret) {            exit("存储数据失败");        }    }    /* 注销数据     * @param string $key     * return bool     */    public function memDestory($key) {        $this->Memcache->set($key);    }    /* Cookie验证,建立客户端与服务器端同步键名     * return bool     */    public function setCookie() {        if (empty($_COOKIE['sessionID'])) {            $sessionID = md5(uniqid(rand(), true)) . $_SERVER['REMOTE_ADDR'];            setcookie('sessionID', $sessionID, time() + SESS_LEFETIME);            $this->set(PREFIX . $sessionID, 'empty');        } else {            setcookie('sessionID', $_COOKIE['sessionID'], time() + SESS_LEFETIME);            if (!$this->Memcache->get(PREFIX . $_COOKIE['sessionID']))                exit('处理异常'); //出现此错误是因为客户端伪造sessionID        }    }}?>

 

下面是简单的测试使用

ceshi.php

<?phprequire_once "memcache.class.php";$config['host'] = '127.0.0.1';$config['port'] = 11211;try {    $session = new MemcacheSession($config);} catch (Exception $e) {    echo $e->getMessage();}$sessionID = PREFIX . $_COOKIE['sessionID'];$data['userA'] = 1024;$data['pointA'] = 100;$data['introA'] = '你干嘛呢!干嘛呢!';$session->set($sessionID, $data);print_r($session->get($sessionID));?>

 

这里仅仅是针对一台服务器的实现。

如果需要分布式存储只需在实例化类传递host时,进行一些扩展就可以实现了。

扩展方案:

1.地址轮询:假设有3台服务器A、B、C,那么当第一个用户访问时连接A,第二个访问时连接B,第三个访问时连接C,第四个访问时返回第一个重新开始计数,依次向下。

2.地址分配:设定三个段A:69.168.0.0-69.168.255.255;B:192.168.0.0-192.168.255.255;C:68.192.0.0-68.192.255.255

当用户访问时,根据IP给其分配对应的服务器。

这两种方法,各自有各自的优缺点。

地址轮询,可以很好的实现负载均衡。

地址分配,可以根据用户位置分配距离最近的服务器,从而提高访问速度。

0 0