PHP中如何使用Redis接管文件存储Session详解


Posted in PHP onNovember 28, 2018

前言

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,代码如下:

<?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功能。因为本例中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文件,代码如下:

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
function.inc.php超越php
Dec 09 PHP
apache2.2.4+mysql5.0.77+php5.2.8安装精简
Apr 29 PHP
Wordpress 相册插件 NextGEN-Gallery 添加目录将中文转为拼音的解决办法
Dec 29 PHP
浅析php面向对象public private protected 访问修饰符
Jun 30 PHP
PHP CURL获取cookies模拟登录的方法
Nov 04 PHP
PHP字符串中特殊符号的过滤方法介绍
Feb 18 PHP
PHP批量生成静态HTML的简单原理和方法
Apr 20 PHP
thinkphp模板的包含与渲染实例分析
Nov 26 PHP
PHP编译安装时常见错误解决办法
May 28 PHP
非常经典的PHP文件上传类分享
May 15 PHP
详解PHP中foreach的用法和实例
Oct 25 PHP
PHP基于SPL实现的迭代器模式示例
Apr 22 PHP
php基于Redis消息队列实现的消息推送的方法
Nov 28 #PHP
php获取用户真实IP和防刷机制的实例代码
Nov 28 #PHP
PHP实现小程序批量通知推送
Nov 27 #PHP
Laravel学习笔记之Artisan命令生成自定义模板的方法
Nov 22 #PHP
关于PHP虚拟主机概念及如何选择稳定的PHP虚拟主机
Nov 20 #PHP
phpMyAdmin通过密码漏洞留后门文件
Nov 20 #PHP
ThinkPHP5 的简单搭建和使用详解
Nov 15 #PHP
You might like
PHP的几个常用数字判断函数代码
2012/04/24 PHP
php设计模式之单例、多例设计模式的应用分析
2013/06/30 PHP
使用PHP curl模拟浏览器抓取网站信息
2013/10/28 PHP
javascript 写类方式之六
2009/07/05 Javascript
jquery向.ashx文件post中文乱码问题的解决方法
2011/03/28 Javascript
javascript setinterval 的正确语法如何书写
2014/06/17 Javascript
浅谈javascript 函数表达式和函数声明的区别
2016/01/05 Javascript
jQuery实现 RadioButton做必选校验功能
2017/06/15 jQuery
在vue项目中引入highcharts图表的方法
2019/01/21 Javascript
angular 服务随记小结
2019/05/06 Javascript
JS中==、===你分清楚了吗
2020/03/04 Javascript
jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作示例
2020/06/02 jQuery
[17:00]DOTA2 HEROS教学视频教你分分钟做大人-帕克
2014/06/10 DOTA
[43:57]LGD vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[01:32]完美世界DOTA2联赛10月29日精彩集锦
2020/10/30 DOTA
python解决汉字编码问题:Unicode Decode Error
2017/01/19 Python
解决python3中自定义wsgi函数,make_server函数报错的问题
2017/11/21 Python
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
Python3获取拉勾网招聘信息的方法实例
2019/04/03 Python
关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题
2020/11/24 Python
h5封装下拉刷新
2020/08/25 HTML / CSS
美国知名玩具品牌:Melissa & Doug
2016/08/16 全球购物
微软英国官方网站:Microsoft英国
2016/10/15 全球购物
SheIn俄罗斯:时尚女装网上商店
2017/02/28 全球购物
金牌葡萄酒俱乐部:Gold Medal Wine Club
2017/11/02 全球购物
英国领先的豪华时尚家居网上商店:Amara
2019/08/12 全球购物
接口可以包含哪些成员
2012/09/30 面试题
媒矿安全生产承诺书
2014/05/23 职场文书
优秀班主任材料
2014/12/16 职场文书
2015年扫黄打非工作总结
2015/05/13 职场文书
家长会感言
2015/08/01 职场文书
2016国庆节67周年红领巾广播稿
2015/12/18 职场文书
爱心捐款倡议书:点燃希望,传递温暖
2019/11/04 职场文书
python opencv检测直线 cv2.HoughLinesP的实现
2021/06/18 Python
vue 把二维或多维数组转一维数组
2022/04/24 Vue.js
Apache Kafka 分区重分配的实现原理解析
2022/07/15 Servers