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 相关文章推荐
destoon整合ucenter后注册页面不跳转的解决方法
Jun 21 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十二)
Jun 25 PHP
php实现屏蔽掉黑帽SEO的搜索关键字
Apr 15 PHP
php里array_work用法实例分析
Jul 13 PHP
PHP与Ajax相结合实现登录验证小Demo
Mar 16 PHP
Zend Framework缓存Cache用法简单实例
Mar 19 PHP
php微信开发之带参数二维码的使用
Aug 03 PHP
php结合ajax实现手机发红包的案例
Oct 13 PHP
详解PHP中mb_strpos的使用
Feb 04 PHP
PHP PDOStatement::fetchAll讲解
Jan 31 PHP
PHP时间函数使用详解
Mar 21 PHP
PHP中的empty、isset、isnull的区别与使用实例
Mar 22 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的POSIX 函数以及进程测试的深入分析
2013/06/03 PHP
PHP中copy on write写时复制机制介绍
2014/05/13 PHP
PHP中的output_buffering详细介绍
2014/09/27 PHP
PHP入门教程之操作符与控制结构流程详解
2016/09/09 PHP
php禁用cookie后session设置方法分析
2016/10/19 PHP
PHP+Redis事务解决高并发下商品超卖问题(推荐)
2020/08/03 PHP
Alliance vs Liquid BO3 第二场2.13
2021/03/10 DOTA
javascript获取当前日期时间及其它操作函数
2011/01/11 Javascript
js中判断数字\字母\中文的正则表达式 (实例)
2012/06/29 Javascript
网站基于flash实现的Banner图切换效果代码
2014/10/14 Javascript
jQuery原生的动画效果
2015/07/10 Javascript
JavaScript中各种引用类型的常用操作方法小结
2016/05/05 Javascript
jQuery绑定事件的几种实现方式
2016/05/09 Javascript
Bootstrap源码学习笔记之bootstrap进度条
2016/12/24 Javascript
bing Map 在vue项目中的使用详解
2018/04/09 Javascript
基于游标的分页接口实现代码示例
2018/11/12 Javascript
简单了解JavaScript sort方法
2019/11/25 Javascript
原生js实现弹窗消息动画
2020/11/20 Javascript
[41:05]Serenity vs Pain 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
python中defaultdict的用法详解
2017/06/07 Python
python ansible服务及剧本编写
2017/12/29 Python
python代码实现逻辑回归logistic原理
2019/08/07 Python
Django错误:TypeError at / 'bool' object is not callable解决
2019/08/16 Python
django-crontab 定时执行任务方法的实现
2019/09/06 Python
双向RNN:bidirectional_dynamic_rnn()函数的使用详解
2020/01/20 Python
Python Pandas数据分析工具用法实例
2020/11/05 Python
python3代码中实现加法重载的实例
2020/12/03 Python
Fossil美国官网:化石手表、手袋、首饰及配饰
2019/02/17 全球购物
品酒会策划方案
2014/05/26 职场文书
教师党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
婚前保证书范文
2015/02/28 职场文书
nginx 反向代理之 proxy_pass的实现
2021/03/31 Servers
Html5大屏数据可视化开发的实现
2021/06/11 HTML / CSS
mysql创建存储过程及函数详解
2021/12/04 MySQL
详细介绍Next.js脚手架完整搭建封装
2022/04/26 Javascript