PHP session文件独占锁引起阻塞问题解决方法


Posted in PHP onMay 12, 2015

PHP默认的会话处理器是session.save_handler = files(即文件)。如果同一个客户端同时并发发送多个请求(如ajax在页面同时发送多个请求),且脚本执行时间较长,就会导致session文件阻塞,影响性能。因为对于每个请求,PHP执行session_start(),就会取得文件独占锁,只有在该请求处理结束后,才会释放独占锁。这样,同时多个请求就会引起阻塞。解决方案如下:

(1)修改会话变量后,立即使用session_write_close()来保存会话数据并释放文件锁。

session_start();
 
$_SESSION['test'] = 'test';
session_write_close();
 
//do something

(2)利用session_set_save_handler()函数是实现自定义会话处理。

function open($savePath, $sessionName)
{
  echo 'open is called';
  return true;
}
 
function close()
{
  echo 'close is called';
  return true;
}
 
function read($sessionId)
{
  echo 'read is called';
  return '';
}
 
function write($sessionId, $data)
{
  echo 'write is called';
  return true;
}
 
function destroy($sessionId)
{
  echo 'destroy is called';
  return true;
}
 
function gc($lifetime)
{
  echo 'gc is called';
  return true;
}
 
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
register_shutdown_function ( 'session_write_close' );
 
session_start();
 
$_SESSION['foo'] = "bar";

当然,在 php 5.4.0之后,你可以通过实现 SessionHandlerInterface 接口或继承 SessionHandler 类来使用。

class MySessionHandler extends SessionHandler {
 
  public function __construct()
  {
  }
 
  public function open($save_path, $session_id)
  {
  }
 
  public function close()
  {
 
  }
 
  public function create_sid()
  {
  }
 
  public function read($id)
  {
  }
 
  public function write($id, $data)
  {
  }
 
  public function destroy($id)
  {
  }
}
 
$handler = new MySessionHandler();
 
//第2个参数将函数 session_write_close() 注册为 register_shutdown_function() 函数。
session_set_save_handler($handler, true);

你可以对上面的代码进行具体实现和封装,利用mysql或其它内存数据库来管理会话数据。还能解决使用集群
时,session数据共享问题。

PHP 相关文章推荐
fleaphp rolesNameField bug解决方法
Apr 23 PHP
php利用iframe实现无刷新文件上传功能的代码
Sep 29 PHP
php操作SVN版本服务器类代码
Nov 27 PHP
php 计划任务 检测用户连接状态
Mar 29 PHP
PHP在网页中动态生成PDF文件详细教程
Jul 05 PHP
QQ互联一键登录审核不通过的解决方案
Sep 10 PHP
php的ZipArchive类用法实例
Oct 20 PHP
php准确计算复活节日期的方法
Apr 18 PHP
PHP输入输出流学习笔记
May 12 PHP
PHP基于cookie与session统计网站访问量并输出显示的方法
Jan 15 PHP
php rmdir使用递归函数删除非空目录实例详解
Oct 20 PHP
PHP给前端返回一个JSON对象的实例讲解
May 31 PHP
PHP获取数组最大值下标的方法
May 12 #PHP
PHP Streams(流)详细介绍及使用
May 12 #PHP
PHP stream_context_create()函数的使用示例
May 12 #PHP
php中使用gd库实现下载网页中所有图片
May 12 #PHP
php中使用gd库实现远程图片下载实例
May 12 #PHP
PHP输入输出流学习笔记
May 12 #PHP
PHP SPL标准库之SplFixedArray使用实例
May 12 #PHP
You might like
PHP中数组的分组排序实例
2014/06/01 PHP
CodeIgniter自定义控制器MY_Controller用法分析
2016/01/20 PHP
必须收藏的php实用代码片段
2016/02/02 PHP
Laravel 创建可以传递参数 Console服务的例子
2019/10/14 PHP
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
2012/08/14 Javascript
js Dialog 实践分享
2012/10/22 Javascript
wap图片滚动特效无css3元素纯js脚本编写
2014/08/22 Javascript
javascript中String对象的slice()方法分析
2014/12/20 Javascript
使用jQuery加载html页面到指定的div实现方法
2016/07/13 Javascript
全面了解函数声明与函数表达式、变量提升
2016/08/09 Javascript
BootStrap的两种模态框方式
2017/05/10 Javascript
jquery dataTable 后台加载数据并分页实例代码
2017/06/07 jQuery
Vue中的ref作用详解(实现DOM的联动操作)
2017/08/21 Javascript
彻底搞懂JavaScript中的apply和call方法(必看)
2017/09/18 Javascript
Nodejs Express 通过log4js写日志到Logstash(ELK)
2018/08/30 NodeJs
JSON.stringify()方法讲解
2019/01/31 Javascript
vue中的v-if和v-show的区别详解
2019/09/01 Javascript
Python中的默认参数详解
2015/06/24 Python
编写Python脚本抓取网络小说来制作自己的阅读器
2015/08/20 Python
浅谈解除装饰器作用(python3新增)
2018/10/15 Python
python 调用有道api接口的方法
2019/01/03 Python
基于OpenCV python3实现证件照换背景的方法
2019/03/22 Python
django 连接数据库 sqlite的例子
2019/08/14 Python
Python中six模块基础用法
2019/12/08 Python
python groupby 函数 as_index详解
2019/12/16 Python
基于python求两个列表的并集.交集.差集
2020/02/10 Python
使用K.function()调试keras操作
2020/06/17 Python
python raise的基本使用
2020/09/10 Python
如何用python开发Zeroc Ice应用
2021/01/29 Python
菲律宾票务网站:StubHub菲律宾
2018/04/21 全球购物
Vision Direct比利时:在线订购隐形眼镜
2019/08/27 全球购物
What's the difference between deep copy and shallow copy? (深拷贝与浅拷贝有什么区别)
2015/11/10 面试题
法律进社区活动总结
2015/05/07 职场文书
2016年寒假生活小结
2015/10/10 职场文书
美德少年主要事迹材料
2015/11/04 职场文书
springboot创建的web项目整合Quartz框架的项目实践
2022/06/21 Java/Android