session_start随机花费40到130秒

时间:2018-12-28 08:13:23

标签: php

我有一个用于身份验证的系统-使用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 = 0memcached.sess_locking = Off-甚至没有使用memcached,但仍然尝试
  • 检查服务器日志并在php端进行概要分析-服务器将请求立即交给php,它在session_start()上挂了一段时间,然后突然完成,脚本立即执行。

让我感到烦恼的是,初始延迟完成后,一切都变得像黄油一样光滑。这让我考虑了大约一分钟后释放的某种锁定,并让脚本正常运行。

我没有尝试过的事情:

  • 将会话处理从默认的基于文件的会话切换到db / memcached / redis /其他任何方式-这可能会解决它,但它并不完全适合我

编辑:清理了实际代码的版本

// 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本身也会重现相同的错误。始终在登录后加载第二页。

2 个答案:

答案 0 :(得分:1)

在撰写本文时,我注意到了问题并加以解决。

home.php页面中有一个地方正在对一个非常慢的脚本进行AJAX调用-一个人也使用了会话,因此挂起了其他所有页面加载,直到完成为止。

以防万一有人偶然发现:

检查WHOLE脚本,尤其是开发工具的“网络”标签。

可能还有其他一些长期运行的请求,导致所有其他请求都延迟了。

答案 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();