session_start()需要非常长的时间

ABT*_*MAT 22 php performance session profiling zend-framework

Mys网站工作非常缓慢(我对其原因一无所知).它基于Zend应用程序,我曾经制作了大约几十个这样的网站,所以我确信我的代码没问题.

我在服务器上安装了xdebugger,尝试对其进行分析并猜测是什么?php :: session_start()花了48.675秒.四十八秒半!这太不可思议了!这可能是什么原因?这是常见的操作,为什么它可以执行SO多长时间?如何修复这种配置编辑的行为?通过谷歌搜索,但没有找到好的答案(几乎所有地方都有问题,但没有答案).谢谢之前!

xdebugger分析结果

goa*_*oat 19

我的猜测是垃圾收集例程,它在本机session_start()函数中运行.也许你已经做了一些能保留很多旧会话文件的东西,比如改变了最长的生命周期?或者你可能已经决定将它们存储在数据库中是一个好主意,但是忘了创建一个合适的索引?本机GC例程stat()用于检查到期的每个会话文件.如果构建了大量文件,这很费时间.

编辑:帮助您进行调试,通过临时设置session.gc-probability禁用垃圾收集:

session.gc-probability = 0
Run Code Online (Sandbox Code Playgroud)

确保设置坚持,我不知道zend框架可能在这里做什么.

PS在不知道原因的情况下很难提出修复建议.我的回答是为了引导您找出原因.


Chr*_*vén 19

session_start(在文件中存储会话)在PHP中是阻塞的,因此如果您尝试为同一个浏览器会话(AJAX或多个浏览器选项卡/窗口)启动多个服务器会话,则会出现此问题.每个session_start会等到其他会话结束.

见这里:http://konrness.com/php5/how-to-prevent-blocking-php-requests/

尝试从会话的文件更改为数据库存储.

  • 谢谢,原来是这样。[session_write_close](http://php.net/manual/en/function.session-write-close.php)帮助了我。 (2认同)

Sam*_*man 6

我遇到了这个问题,并且很惊讶没有人发布这个特定的回复.它可能不是它,但值得检查.

PHP在页面处理时锁定会话文件,以便该页面可以独占访问它.考虑一下,sess_184c9aciqoc文件不是数据库,因此同一会话中的两个调用不能同时访问它.因此,如果您有很多ajax呼叫,您可能会遇到"交通堵塞".一旦你开始进行高级脚本编写,这是一个需要注意的问题.顺便说一句,这是一个存储时间戳数组的函数.我用这个来弄清楚会话开始是罪魁祸首:

//time function for benchmarking
if( function_exists('gmicrotime')){
    function gmicrotime($n=''){
        #version 1.1, 2007-05-09
        //store array of all calls
        global $mT;
        list($usec, $sec) = explode(' ',microtime());
        if(!isset($mT['_base_']))$mT['_base_']=$sec;
    $t=round((float)$usec + (float)(substr($sec,-4)),6);
    $mT['all'][]=$t;
    if($n){
        if(isset($mT['indexed'][$n])){
            //store repeated calls with same index.  If in a loop, add a $i if needed
            if(is_array($mT['indexed'][$n])){
                $mT['indexed'][$n][]=$t;
            }else{
                $mT['indexed'][$n]=array($mT['indexed'][$n],$t);
            }
        }else $mT['indexed'][$n]=$t;    
    }
    //return elapsed since last call (in the local array)
    $u=$mT['all'];
    if(count($u)>1){
        $mT['_total_']=$u[count($u)-1] - $u[0];
        return round(1000*($u[count($u)-1]-$u[count($u)-2]),6);
    }
}
gmicrotime('pageStart');
}
Run Code Online (Sandbox Code Playgroud)

然后我打电话如下:

gmicrotime('beforeSessionStart');
session_start();
gmicrotime('afterSessionStart');

do_something_slow();
gmicrotime('afterSlowProcess');
//etc..
echo '<pre>';
print_r($mT);  
Run Code Online (Sandbox Code Playgroud)

希望这有用!