前言

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,输出结果如下所示:

再查看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://www.geek-share.com/detail/2754800685.html

PHP中使用Redis接管文件存储Session详解的更多相关文章

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

    https://www.jb51.net/article/151580.htm 前言 php默认使用文件存储session,如果并发量大,效率会非常低.而redis对高并发的支持非常好,可以利用red ...

  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. 巨人大哥谈Web应用中的Session(session详解)

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

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

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

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

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

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

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

  8. Cookie与Session详解

    来源:<PHP核心技术与最佳实践> 列旭松 陈文 著 Cookie与Session详解读书笔记,从概念.操作.应用.注意事项以及区别等几方面详细阐述两者的基础知识,它们都是针对HTTP协议 ...

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

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

随机推荐

  1. 用POP动画编写带富文本的自定义动画效果

    用POP动画编写带富文本的自定义动画效果 [源码] https://github.com/YouXianMing/UI-Component-Collection [效果] [特点] * 支持富文本 * ...

  2. 创建 In-app Billing 商品

    创建可供购买的 In-app Billing 商品 在你发布 In-app Billing 应用前,你需要在 Google Play 开发者控制台 定义可供购买的数字商品列表. 在 Google Pl ...

  3. 企业级Apache详解

    安装Apache #Apache安装 rpm -qa|grep httpd yum install httpd #2编译安装: -->推荐安装 cd /root/software yum -y ...

  4. 阿里云Quick BI——让人人都成为分析师

    在3月29日深圳云栖大会的数据分析与可视化专场中,阿里云产品专家潘炎峰(陌停)对大数据智能分析产品 Quick BI 进行了深入的剖析.大会现场的精彩分享也赢得观众们的一直认可和热烈的反响. Quic ...

  5. 沉淀再出发:再谈java的多线程机制

    沉淀再出发:再谈java的多线程机制 一.前言 自从我们学习了操作系统之后,对于其中的线程和进程就有了非常深刻的理解,但是,我们可能在C,C++语言之中尝试过这些机制,并且做过相应的实验,但是对于ja ...

  6. August 19th 2017 Week 33rd Saturday

    Live for today and stop stressing out about tomorrow. 为今天而活,不必为明天过分担心. Stop bewailing the past misfo ...

  7. Centos7安装Redis4.0.8

    今天安装了CentOS7 1708 在安装redis时报错  make[1]: *** [adlist.o] 错误 127 因为Redis是C实现的,需要gcc来进行编译,所以原因是系统未安装gcc, ...

  8. Vue实现购物小球抛物线

    .shop{ position: fixed; top: 300px; left: 40px; } .ball{ position: fixed; left: 32px; bottom: 22px; ...

  9. 2、Android-UI(关于Nine-Patch图片)

    实例: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...

  10. browserify文件后函数调用报is not defined的原因

    举个例子: a.js ; module.exports.a = a; b.js var result = require('./a'); var getA =() => { console.lo ...