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对象类型判断
Aug 27 PHP
php foreach循环中使用引用的问题
Nov 06 PHP
PHP开发微信支付的代码分享
May 25 PHP
抛弃 PHP 代价太高
Apr 26 PHP
PHP基于反射机制实现插件的可插拔设计详解
Nov 10 PHP
laravel创建类似ThinPHP中functions.php的全局函数
Nov 26 PHP
php实现的rc4加密解密类定义与用法示例
Aug 16 PHP
PHP实现的数据对象映射模式详解
Mar 20 PHP
Laravel5.0+框架邮件发送功能实现方法图文与实例详解
Apr 23 PHP
PHP实现统计代码行数小工具
Sep 19 PHP
浅析PHP中的 inet_pton 网络函数
Dec 16 PHP
linux mint下安装phpstorm2020包括JDK部分的教程详解
Sep 17 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
Zend Framework中的简单工厂模式 图文
2012/07/10 PHP
php中base64_decode与base64_encode加密解密函数实例
2014/11/24 PHP
PHP单链表的实现代码
2016/07/05 PHP
PHP简单实现二维数组的矩阵转置操作示例
2017/11/24 PHP
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
2014/06/10 Javascript
JS实现往下不断流动网页背景的方法
2015/02/27 Javascript
jQuery通过扩展实现抖动效果的方法
2015/03/11 Javascript
JavaScript知识点总结(十一)之js中的Object类详解
2016/05/31 Javascript
AngularJS入门教程之控制器详解
2016/07/27 Javascript
深入浅出ES6新特性之函数默认参数和箭头函数
2016/08/01 Javascript
利用node.js本地搭建HTTP服务器
2017/04/19 Javascript
详解Vuejs2.0 如何利用proxyTable实现跨域请求
2017/08/03 Javascript
服务端预渲染之Nuxt(使用篇)
2019/04/08 Javascript
vue滚动tab跟随切换效果
2020/06/29 Javascript
JQuery事件委托(适用于给动态生成的脚本元素添加事件)
2020/02/01 jQuery
[01:14:12]2018DOTA2亚洲邀请赛4.7 总决赛 LGD vs Mineski 第二场
2018/04/09 DOTA
Python实现简单截取中文字符串的方法
2015/06/15 Python
全面了解python字符串和字典
2016/07/07 Python
python timestamp和datetime之间转换详解
2017/12/11 Python
Python中getpass模块无回显输入源码解析
2018/01/11 Python
PyQt5笔记之弹出窗口大全
2019/06/20 Python
如何使用django的MTV开发模式返回一个网页
2019/07/22 Python
django 通过url实现简单的权限控制的例子
2019/08/16 Python
浅谈pytorch池化maxpool2D注意事项
2020/02/18 Python
python脚本实现mp4中的音频提取并保存在原目录
2020/02/27 Python
django列表筛选功能的实现代码
2020/03/27 Python
Django数据库操作之save与update的使用
2020/04/01 Python
Django使用rest_framework写出API
2020/05/21 Python
HTML5的结构和语义(4):语义性的内联元素
2008/10/17 HTML / CSS
HTML5 Canvas渐进填充与透明实现图像的Mask效果
2013/07/11 HTML / CSS
阿迪达斯加拿大官网:Adidas加拿大
2016/08/25 全球购物
Laura Mercier官网:彩妆大师罗拉玛斯亚的化妆品牌
2018/01/04 全球购物
德国汽车零件和汽车配件网上商店:kfzteile24
2018/11/14 全球购物
Columbia Sportswear法国官网:全球户外品牌
2020/09/25 全球购物
网页美工求职信
2014/02/15 职场文书
网络安全倡议书(3篇)
2019/09/18 职场文书