内容简介:之前找了网上的一套直播系统给客户用,刚开始是没问题的,在后面人数上来之后网站开始变得卡顿,卡的一批。之后查看php慢日志发现因为这套直播系统一没有用框架,二没有设计规范,各种session操作散落在不同的文件里,用第一个解决方案完全属于费力不讨好。再者直播系统的聊天互动等功能已经涉及大量的mysql操作,再用mysql接管session变相的增加了数据库的压力,最终确定了使用redis接管session。php有内置的操作session的save_handler,使用
之前找了网上的一套直播系统给客户用,刚开始是没问题的,在后面人数上来之后网站开始变得卡顿,卡的一批。之后查看 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
的前两行,成功接管,舒服。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 第十八篇:CSRF导致账号接管
- 图解源码 | 接管SpringMVC的自动配置
- 通过暴露的docker.sock文件接管容器
- GandCrab后继有人?Sodinoki勒索软件接管战场
- 有漏洞!黑客可以完全接管你的路由器
- Wordpress 插件出现漏洞,网站可能被攻击者接管
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。