我有一个用于身份验证的系统-使用php会话。
问题是,似乎随机地,session_start()成功(在40到130秒之间)执行了。
我能够重现该问题的唯一方法是先注销(先登录session_unset()
,然后再登录session_destroy()
,然后重定向到登录页面),然后再次登录(随后是session_start()
通过设置一些会话变量)。
此时,页面立即加载。但是,一旦我从该页面中加载另一个页面, any ,就会花费很多时间。完成后,我可以立即加载所有页面。
立即加载的页面与需要花费大量时间的页面没有区别-在两种情况下,都只是
<?php
session_start();
die('session started');
问题并不总是存在的-它是在几周前开始的,可能是在托管者进行了一些更新之后。可以在任何地方的任何浏览器上复制它。
我尝试过的事情:
session_start()
之后跟随session_write_close()
session.lazy_write = 0
和memcached.sess_locking = Off
-甚至没有使用memcached,但仍然尝试session_start()
上挂了一段时间,然后突然完成,脚本立即执行。让我感到烦恼的是,初始延迟完成后,一切都变得像黄油一样光滑。这让我考虑了大约一分钟后释放的某种锁定,并让脚本正常运行。
我没有尝试过的事情:
编辑:清理了实际代码的版本
// login.php
<?php
if (login()) {
session_start();
$_SESSION['login'] = true;
/**
* some more session variables being set, taken from the db - they're not too many and
* they're pretty simple strings and booleans
*/
header('Location: home.php');
exit();
}
此后,用户将重定向到home.php-一个非常基本的页面,仅显示一些信息(其中一部分来自会话) 但不将任何内容写入会话
// home.php
<?php
session_start();
// well, the rest of the code
现在,如果我尝试导航到任何其他页面,则session_start()是SLOOOOOW。为了简单起见,我将使用注销
以网页为例-我们在网址栏中输入site.com/logout.php
,然后按Enter。
然后,等待一分钟以使session_start()成功完成;
logout.php很简单:
// logout.php
<?php
session_start();
session_unset();
session_destroy();
header('Location: index.php');
exit();
等待一分钟后,我们成功注销。我们可以再次登录并重复相同的情况, 在home.php之后的后续页面加载中。
即使重新加载home.php本身也会重现相同的错误。始终在登录后加载第二页。
答案 0 :(得分:1)
在撰写本文时,我注意到了问题并加以解决。
home.php页面中有一个地方正在对一个非常慢的脚本进行AJAX调用-一个人也使用了会话,因此挂起了其他所有页面加载,直到完成为止。
以防万一有人偶然发现:
可能还有其他一些长期运行的请求,导致所有其他请求都延迟了。
答案 1 :(得分:0)
原因是PHP在请求完成之前不会释放会话。因此,如果有任何先前的请求待处理,则会话被锁定,而下一个请求在session_start()命令处被阻塞。为避免此问题,如果您不写入会话,则将会话数据读取到本地变量后,即可使用session_write_close();。以防止会话锁定。而且,如果您必须再次写入会话,则必须在之前使用session_start()。
session_start();
$_SESSION['user'] = 'foo';
$_SESSION['role'] = 'foo1';
session_write_close();
....
....
session_start();
$_SESSION['userid'] = 1;
session_write_close();