https://www.jb51.net/article/151580.htm

前言

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

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

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

解决方案

  • 将session全面更换为cookie

  • 使用mysql或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,输出结果如下所示:

再查看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中如何使用Redis接管文件存储Session详解的更多相关文章

  1. PHP中使用Redis接管文件存储Session详解

    前言 php默认使用文件存储session,如果并发量大,效率会非常低.而redis对高并发的支持非常好,可以利用redis替换文件来存储session. 最近就遇到了这个问题,之前找了网上的一套直播 ...

  2. PHP中Redis替代文件存储Session语句

    php默认使用文件存储session,如果并发量大,效率非常低.而Redis对高并发的支持非常好,所以,可以使用redis替代文件存储session. 这里,介绍下php的 session_set_s ...

  3. Linux中redis安装配置及使用详解

    Linux中redis安装配置及使用详解 一. Redis基本知识 1.Redis 的数据类型 字符串 , 列表 (lists) , 集合 (sets) , 有序集合 (sorts sets) , 哈 ...

  4. Mybatis中接口和对应的mapper文件位置配置详解

    Mybatis中接口和对应的mapper文件位置配置详解 原链接为:https://blog.csdn.net/fanfanzk1314/article/details/71480954 今天遇到一个 ...

  5. Python中__init__.py文件的作用详解

    转自http://www.jb51.net/article/92863.htm Python中__init__.py文件的作用详解 http://www.jb51.net/article/86580. ...

  6. php中读取大文件实现方法详解

    php中读取大文件实现方法详解 来源:   时间:2013-09-05 19:27:01   阅读数:6186 分享到:0 [导读] 本文章来给各位同学介绍php中读取大文件实现方法详解吧,有需要了解 ...

  7. 深入浅出—Redis集群的相关详解

    前言: 这篇文章主要介绍了Redis集群的相关,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值. 注意!要求使用的都是redis3.0以上的版本,因为3.0以上增加了red ...

  8. C#文件后缀名详解

    C#文件后缀名详解 .sln:解决方案文件,为解决方案资源管理器提供显示管理文件的图形接口所需的信息. .csproj:项目文件,创建应用程序所需的引用.数据连接.文件夹和文件的信息. .aspx:W ...

  9. 巨人大哥谈Web应用中的Session(session详解)

    巨人大哥谈Web应用中的Session(session详解) 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术. ...

随机推荐

  1. centos升级数据库

    Centos下升级MySQL数据库 备份数据 $ mysqldump -u xxx -h xxx -P 3306 -p --all-databases > databases.sql 查看版本 ...

  2. 网站漏洞检测之WordPress 5.0.0 系统修复方案

    2019年正月刚开始,WordPress最新版本存在远程代码注入获取SHELL漏洞,该网站漏洞影响的版本是wordpress5.0.0,漏洞的产生是因为image模块导致的,因为代码里可以进行获取目录 ...

  3. UART学习之路(四)VerilogHDL实现的简单UART,VIVADO下完成仿真

    用VerilogHDL实现UART并完成仿真就算是对UART整个技术有了全面的理解,同时也算是Verilog入门了.整个UART分为3部分完成,发送模块(Transmitter),接收模块(Recei ...

  4. telnet 批处理

    **** 需要确认多台服务器端口是否打开,如果一个一个telnet会非常麻烦,通过百度,写了两个BAT,基本能做工作需要. ***start.bat start "" " ...

  5. canvas画的文字在安卓移动设备上可以显示,但是在ios移动设备上无法显示

    不用担心iOS Safari不支持canvas,查看https://caniuse.com/ 发现是支持的 ctx.font = "0.16rem Arial"; 为了适配移动端直 ...

  6. 线上CPU飚高(死循环,死锁...)

    之前排除服务器内存暴增的问题,在此看到一篇类似的文章,做个类似的记录. 1.top基本使用 top 命令运行图: 第一行:基本信息 第二行:任务信息 第三行:CPU使用情况 第四行:物理内存使用情况 ...

  7. 20145202马超《网络对抗》Exp9*_* Web安全基础实践

    本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 1.实验后回答问题 (1)SQL注入攻击原理,如何防御 感觉上次做的也是sql注入,就是故意的非法输入(输入的是一些指令)让 ...

  8. cyclone4驱动LM75A温湿度传感器学习

    1. LM75A第一次使用,I2C接口,8脚 2. 打开quartus工程,下面只要是看看代码结构,问题在于多个always语句,逻辑上不太好分清楚,主要看状态机 module I2C_READ( c ...

  9. mysql using filesort Using temporary

    using filesort 一般人的回答是: “当行数据太大,导致内存无法容下这些数据产生的临时表时,他们就会被放入磁盘中排序.”  很不幸,这个答案是错的 ,临时表在太大的时候确实会到磁盘离去,但 ...

  10. 最新flowable研究学习及其汉化flowable6.3中文

    flowable 是activiti的分支,现在感觉比activiti要强大一些,官网是 https://flowable.org/ 下载最新的6.31版本. 放到tomcat下面,汉化需要对flow ...