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 相关文章推荐
Classes and Objects in PHP5-面向对象编程 [1]
Oct 09 PHP
使用php4加速网络传输
Oct 09 PHP
PHP 批量删除数据的方法分析
Oct 30 PHP
10 个经典PHP函数
Oct 17 PHP
PHP屏蔽过滤指定关键字的方法
Nov 03 PHP
PHP 使用memcached简单示例分享
Mar 05 PHP
PHP实现将视频转成MP4并获取视频预览图的方法
Mar 12 PHP
php文件上传 你真的掌握了吗
Nov 28 PHP
yii 2.0中表单小部件的使用方法示例
May 23 PHP
yii2中LinkPager增加总页数和总记录数的实例
Aug 28 PHP
Ubuntu上安装yaf扩展的方法
Jan 29 PHP
Laravel 集成 Geetest验证码的方法
May 14 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
vBulletin HACK----关于排版的两个HACK
2006/10/09 PHP
详解PHP防止直接访问.php 文件的实现方法
2017/07/28 PHP
PHP基于phpqrcode类生成二维码的方法详解
2018/03/14 PHP
PHP实现负载均衡下的session共用功能
2018/04/17 PHP
jQuery $.data()方法使用注意细节
2012/12/31 Javascript
javascript 常见功能汇总
2015/06/11 Javascript
javascript实现简单的进度条
2015/07/02 Javascript
javascript嵌套函数和在函数内调用外部函数的区别分析
2016/01/31 Javascript
仿Angular Bootstrap TimePicker创建分钟数-秒数的输入控件
2016/07/01 Javascript
微信小程序 label 组件详解及简单实例
2017/01/10 Javascript
ES6新特性三: Generator(生成器)函数详解
2017/04/21 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
2017/07/03 Javascript
JavaScript实现二叉树定义、遍历及查找的方法详解
2017/12/20 Javascript
浅谈Vue2.0父子组件间事件派发机制
2018/01/08 Javascript
js代码规范之Eslint安装与配置详解
2018/09/08 Javascript
小程序获取周围IBeacon设备的方法
2018/10/31 Javascript
vue+element-ui实现表格编辑的三种实现方式
2018/10/31 Javascript
使用puppeteer爬取网站并抓出404无效链接
2018/12/20 Javascript
富文本编辑器vue2-editor实现全屏功能
2019/05/26 Javascript
js实现内置计时器
2019/12/16 Javascript
JavaScript实现Excel表格效果
2020/02/07 Javascript
js实现轮播图效果 纯js实现图片自动切换
2020/08/09 Javascript
解决vue scoped scss 无效的问题
2020/09/04 Javascript
[01:11:46]DOTA2-DPC中国联赛 正赛 iG vs Magma BO3 第一场 2月23日
2021/03/11 DOTA
python生成指定长度的随机数密码
2014/01/23 Python
python数据类型_元组、字典常用操作方法(介绍)
2017/05/30 Python
使用python实现抓取腾讯视频所有电影的爬虫
2019/04/15 Python
python实现文件助手中查看微信撤回消息
2019/04/29 Python
Python BeautifulReport可视化报告代码实例
2020/04/13 Python
Python HTMLTestRunner库安装过程解析
2020/05/25 Python
CSS实现进度条和订单进度条的示例
2020/11/05 HTML / CSS
Ray-Ban雷朋美国官网:全球领先的太阳眼镜品牌
2016/07/20 全球购物
日本卡普空电视游戏软件公司官方购物网站:e-CAPCOM
2018/07/17 全球购物
迟到早退检讨书
2014/02/10 职场文书
2014年两会学习心得体会
2014/03/17 职场文书
幼儿教师师德师风自我剖析材料
2014/09/29 职场文书