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

前言php

php默认使用文件存储session,若是并发量大,效率会很是低。而redis对高并发的支持很是好,能够利用redis替换文件来存储session。html

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

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

解决方案redis

  • 将session全面更换为cookie
  • 使用mysql或redis接管session

坑中坑sql

由于这套直播系统一没有用框架,二没有设计规范,各类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。cookie

(如下代码来源于网络,也不知道原创是哪位大佬)网络

编写一个session管理类sessionManager.php,代码以下:session

<?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

相关文章
相关标签/搜索