博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP中使用Redis接管文件存储Session详解
阅读量:7075 次
发布时间:2019-06-28

本文共 2445 字,大约阅读时间需要 8 分钟。

  hot3.png

前言

php默认使用文件存储session,如果并发量大,效率会非常低。而redis对高并发的支持非常好,可以利用redis替换文件来存储session。

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

[0x00007fff67ee6740] session_start()[0x00007fff67ee7b70] +++ dump failed

解决方案

  • 将session全面更换为cookie
  • 使用mysql或redis接管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,代码如下:

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功能。因为本例中open、close和gc回调函数的作用不是很大,所以直接返回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文件,代码如下:

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

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

bbd781b9557aba0eddeea7136bc5d2eb

再查看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的前两行,成功接管,舒服。

您可能感兴趣的文章:

文章同步发布: 

转载于:https://my.oschina.net/os2015/blog/2967182

你可能感兴趣的文章
大数据教程(2.5):Linux系统搭建本地YUM源服务器
查看>>
postgreSQL中如何实现group_concat
查看>>
招聘网工:内推性质
查看>>
wxPython,线程中修改UI的方法
查看>>
Snapshot Volume 操作 - 每天5分钟玩转 OpenStack(58)
查看>>
Composer : php依赖管理工具
查看>>
5 秒创建 k8s 集群 - 每天5分钟玩转 Docker 容器技术(115)
查看>>
jQuery学习和知识点总结归纳
查看>>
Permission denied You (root) are not allowed to access to (crontab) because of pam configuration.
查看>>
mybaits出现错误
查看>>
我的友情链接
查看>>
如果项目使用HOLO或加载V7包就会出现小按钮变大
查看>>
kvm虚拟化
查看>>
自制WheelView沉浸式菜单及Dialog样式Activity
查看>>
python-62: BS4的基本知识
查看>>
jsp中文显示乱码的解决办法
查看>>
Cmakelists.txt中间部分模板
查看>>
eclipse中java工程转web工程
查看>>
linux中的僵尸进程
查看>>
clustershell批量执行shell命令
查看>>