您的位置:首页 > 编程语言 > PHP开发

php session读写锁引起的脚本阻塞问题

2015-04-26 22:22 701 查看
项目中经常会遇到session引起的脚本阻塞问题。比如一个需要操作session的页面接口长时间不响应,会导致其他操作session的页面也打不开。一直到接口响应或者超时才能操作其他。还有就是用session做登录的页面需要大量时间去执行数据库操作时间也会引起的脚本阻塞。在session_start()后 对应的session文件是被锁定的,直到当前脚本结束才会解锁。在锁定期间另一个进程访问相同session id需要等session解锁后,才能开始读写session.
解决这个问题就是在 session 设置好数据后调用 session_write_close() 将数据写入并且结束session解锁,这样就不会影响页面访问速度。

下面是我写的一个测试session锁的例子

<?php
/**
* 未使用 session_write_close 打开其他页面非常慢
*/
session_start();
$_SESSION['test'] = date("Y-m-d H:i:s");
echo $_SESSION['test'],PHP_EOL,"<br/>";
sleep(10);
?>
<p><a target="_blank" href="/session/2.php">显示session</a></p>


2.php

<?php
/**
* 未使用 session_write_close 打开其他页面非常慢
*/
$startTime = microtime(true);
session_start();
var_dump($_SESSION);
echo  date("Y-m-d H:i:s"),PHP_EOL,"<br/>";
$endTime = microtime(true);
echo  "打开时间",$endTime-$startTime,PHP_EOL,"<br/>";
?>
<p><a href="/session/1.php">session锁定</a></p>
<p><a href="/session/3.php">session不锁定</a></p>

3.php
<?php
/**
* 使用 session_write_close 打开其他页面非常快
*/
session_start();
$_SESSION['test'] = date("Y-m-d H:i:s");
echo $_SESSION['test'],PHP_EOL,"<br/>";
session_write_close();
sleep(10);

?>
<p><a href="/session/2.php">显示session</a></p>


例子1 用浏览器打开1.php,然后再打开2.php。发现2.php非常慢,一直要等到1.php执行完了2.php才响应这就是session引起的脚本阻塞问题。

例子2  用浏览器打开3.php,然后再打开2.php。发现2.php一会就找开的,比3.php响就快。对比这两个文件发现就多一行代码,session_write_close。其实道理很简单,session用完就关闭。这样就不会影响到其他session的读写操作了。具体看下php手册上摘抄的详细说明

下面是php手册关于 session_write_close的说明 

php API 说明 

(PHP 4 >= 4.0.4, PHP 5)
session_write_close —
Write session data and end session

说明

void
session_write_close ( void )

session_write_close

结束当前会话和存储会话数据。

会话数据通常存储在您的脚本终止而不需要调用session_write_close(),但随着会话数据锁定,防止并发写脚本可能只有一个操作在任何时候一个会话。当使用框架集一起会议你将体验到帧加载一个接一个因锁定。可以减少所需的时间来加载所有的帧结束会话当所有更改会话变量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息