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 相关文章推荐
php 截取字符串并以零补齐str_pad() 函数
May 07 PHP
php处理斐波那契数列非递归方法
Feb 04 PHP
php多文件上传下载示例分享
Feb 20 PHP
php获取服务器端mac和客户端mac的地址支持WIN/LINUX
May 15 PHP
CI使用Tank Auth转移数据库导致密码用户错误的解决办法
Jun 12 PHP
php实现简易聊天室应用代码
Sep 23 PHP
php微信开发之上传临时素材
Jun 24 PHP
示例详解Laravel的注册重构
Aug 14 PHP
PHP中文字符串截断无乱码解决方法
Oct 10 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
ThinkPHP5与单元测试PHPUnit使用详解
Feb 23 PHP
php使用redis的有序集合zset实现延迟队列应用示例
Feb 20 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 ios推送(代码)
2013/07/01 PHP
php比较两个字符串长度的方法
2015/07/13 PHP
UTF-8正则表达式如何匹配汉字
2015/08/03 PHP
PHP防盗链的基本思想 防盗链的设置方法
2015/09/25 PHP
PHP中如何使用Redis接管文件存储Session详解
2018/11/28 PHP
PHP单文件上传原理及上传函数的封装操作示例
2019/09/02 PHP
一个javascript参数的小问题
2008/03/02 Javascript
javscript对象原型的一些看法
2010/09/19 Javascript
jQuery实现的Email中的收件人效果(按del键删除)
2011/03/20 Javascript
读jQuery之十 事件模块概述
2011/06/27 Javascript
javascript字母大小写转换的4个函数详解
2014/05/09 Javascript
js实现按钮加背景图片常用方法
2014/11/01 Javascript
JavaScript中的原型prototype属性使用详解
2015/06/05 Javascript
简介AngularJS的HTML DOM支持情况
2015/06/17 Javascript
判断输入的字符串是否是日期格式的简单方法
2016/07/11 Javascript
用js实现before和after伪类的样式修改的示例代码
2017/09/07 Javascript
[06:45]DOTA2-DPC中国联赛 正赛 Magma vs LBZS 选手采访
2021/03/11 DOTA
[16:01]夜魇凡尔赛茶话会 第二期01:你比划我猜
2021/03/11 DOTA
python自动发送邮件脚本
2018/06/20 Python
TensorFlow实现iris数据集线性回归
2018/09/07 Python
详解Python3中的迭代器和生成器及其区别
2018/10/09 Python
Django高级编程之自定义Field实现多语言
2019/07/02 Python
美国一家全面的在线零售鞋类公司:SHOEBACCA
2017/01/06 全球购物
英国最大的老式糖果店:A Quarter Of
2017/04/08 全球购物
DJI美国:消费类无人机领域的领导者
2018/04/27 全球购物
银行类自荐信
2014/02/04 职场文书
初中家长寄语
2014/04/02 职场文书
护理专业求职信
2014/06/15 职场文书
公司采购主管岗位职责
2014/06/17 职场文书
小学生春游活动方案
2014/08/20 职场文书
政风行风整改方案
2014/10/25 职场文书
电视新闻稿
2015/07/17 职场文书
2019年世界儿童日宣传标语
2019/11/22 职场文书
Java生成读取条形码和二维码的简单示例
2021/07/09 Java/Android
Python 详解通过Scrapy框架实现爬取百度新冠疫情数据流程
2021/11/11 Python
Redis中key的过期删除策略和内存淘汰机制
2022/04/12 Redis