PHP中使用Redis接管文件存储Session

栏目: PHP · 发布时间: 5年前

内容简介:之前找了网上的一套直播系统给客户用,刚开始是没问题的,在后面人数上来之后网站开始变得卡顿,卡的一批。之后查看php慢日志发现因为这套直播系统一没有用框架,二没有设计规范,各种session操作散落在不同的文件里,用第一个解决方案完全属于费力不讨好。再者直播系统的聊天互动等功能已经涉及大量的mysql操作,再用mysql接管session变相的增加了数据库的压力,最终确定了使用redis接管session。php有内置的操作session的save_handler,使用

之前找了网上的一套直播系统给客户用,刚开始是没问题的,在后面人数上来之后网站开始变得卡顿,卡的一批。之后查看 php 慢日志发现 session_start() 的身影,好吧,原来是万恶的文件存储session,跟我之前进的坑一模一样……之前做的教务查询系统直接用的session没有用cookie,结果在高并发的情况下php原地爆炸。

[0x00007fff67ee6740] session_start()
[0x00007fff67ee7b70] +++ dump failed
复制代码

解决方案

  1. session 全面更换为 cookie
  2. 使用 mysqlredis 接管 session

坑中坑

因为这套直播系统一没有用框架,二没有设计规范,各种session操作散落在不同的文件里,用第一个解决方案完全属于费力不讨好。再者直播系统的聊天互动等功能已经涉及大量的 mysql 操作,再用mysql接管session变相的增加了数据库的压力,最终确定了使用 redis 接管session。

具体实现

php有内置的操作session的save_handler,使用 session_set_save_handler ,接管所有的session管理工作。在使用该函数前,先把php.ini配置文件的 session.save_handler 选项设置为user,否则 session_set_save_handle 不会生效。另外除了安装redis之外,php扩展也需要增加redis。

(以下代码来源于网络,也不知道原创是哪位大佬) 编写一个session管理类sessionManager.php,代码如下:

<?php
class SessionManager{

    private $redis;
    private $sessionSavePath;
    private $sessionName;
    private $sessionExpireTime=30;//redis,session的过期时间为30s

    public function __construct(){
        $this->redis = new Redis();//创建phpredis实例
        $this->redis->connect('127.0.0.1',6379);//连接redis
        $this->redis->auth("107lab");//授权
        $retval = session_set_save_handler(
            array($this,"open"),
            array($this,"close"),
            array($this,"read"),
            array($this,"write"),
            array($this,"destroy"),
            array($this,"gc")
        );
        session_start();
    }

    public function open($path,$name){
        return true;
    }

    public function close(){
        return true;
    }

    public function read($id){
        $value = $this->redis->get($id);//获取redis中的指定记录
        if($value){
            return $value;
        }else{
            return '';
        }
    }

    public function write($id,$data){
        if($this->redis->set($id,$data)){//以session ID为键,存储
            $this->redis->expire($id,$this->sessionExpireTime);//设置redis中数据的过期时间,即session的过期时间
            return true;
        }

        return false;
    }

    public function destroy($id){
        if($this->redis->delete($id)){//删除redis中的指定记录
            return true;
        }
        return false;
    }

    public function gc($maxlifetime){
        return true;
    }

    public function __destruct(){
        session_write_close();
    }

}
复制代码

SessionManager 构造函数主要用来连接Redis服务器,使用 session_set_save_handler 函数设置session回调函数,并调用 session_start 函数开启session功能。因为本例中 openclosegc 回调函数的作用不是很大,所以直接返回true。

在write回调函数中,以session ID 作为key,把session的数据作为value存储到redis服务器,设置session的过期时间为30秒。在 read 回调函中,以session ID 作为key从redis服务器中读取数据,并返回此数据。而在 destroy 回调函数重,则以session ID 作为key 从redis服务器中删除对应的session数据。

使用时,只需包含SessionManager类,然后实例化一个SessionManager对象。 下面建立个session_set.php文件,代码如下:

<?php
    include('SessionManager.php');
    new SessionManager();
    $_SESSION['username'] = 'captain';
复制代码

然后再创建一个session_get.php文件,代码如下:

<?php
    include('SessionManager.php');
    new SessionManager();
    echo $_SESSION['username'];
复制代码

测试时,首先访问 session_set.php ,然后再访问 session_get.php ,输出结果如下所示:

PHP中使用Redis接管文件存储Session

再查看redis数据库,如下所示:

127.0.0.1:6379> keys *
1) "oe94eic337slnjv1bvlreoa574"
127.0.0.1:6379> get oe94eic337slnjv1bvlreoa574
"username|s:7:\"captain\";"
复制代码

测试完美~ 然后将原系统中的 session_start() 替换成 session_set.php 的前两行,成功接管,舒服。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

未来简史

未来简史

[以色列] 尤瓦尔·赫拉利 / 林俊宏 / 中信出版集团 / 2017-2 / 68.00元

进入21世纪后,曾经长期威胁人类生存、发展的瘟疫、饥荒和战争已经被攻克,智人面临着新的待办议题:永生不老、幸福快乐和成为具有“神性”的人类。在解决这些新问题的过程中,科学技术的发展将颠覆我们很多当下认为无需佐证的“常识”,比如人文主义所推崇的自由意志将面临严峻挑战,机器将会代替人类做出更明智的选择。 更重要的,当以大数据、人工智能为代表的科学技术发展的日益成熟,人类将面临着从进化到智人以来z......一起来看看 《未来简史》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具