2014-09-24 70 views
6

注意这是而不是一个愚蠢的PHP session_start() causing HTTP requests to hang(和其他类似命名的问题上SO),因为我的挂钩偶尔,而不是永久性的。为什么PHP偶尔挂在session_start()

使用Ubuntu 12.04,Magento,PHP-FPM (5.4)和默认的PHP会话处理程序(在ext4上有文件)。

顺便提及(once per month)所有PHP进程上session_start()挂起(根据FPM-的slow.log):

[24-Sep-2014 11:03:04] [pool www] pid 24259 
script_filename = /data/web/public/index.php 
[0x00007f00b4ec6480] session_start() /data/web/public/includes/src/__default.php:7687 
[0x00007f00b4ec6130] start() /data/web/public/includes/src/__default.php:7730 
[0x00007f00b4ec5fb8] init() /data/web/public/includes/src/__default.php:8086 
[0x00007f00b4ec5e30] init() /data/web/public/includes/src/__default.php:33902 
[0x00007f00b4ec5bd0] __construct() /data/web/public/includes/src/__default.php:23841 
[0x00007f00b4ec5ae8] getModelInstance() /data/web/public/app/Mage.php:463 
[0x00007f00b4ec59c8] getModel() /data/web/public/app/Mage.php:477 
[0x00007f00b4ec49a0] getSingleton() /data/web/public/includes/src/__default.php:14044 
[0x00007f00b4ec4848] preDispatch() /data/web/public/includes/src/Mage_Adminhtml_Controller_Action.php:160 
[0x00007f00b4ec3b00] preDispatch() /data/web/public/includes/src/__default.php:13958 
[0x00007f00b4ec26e0] dispatch() /data/web/public/includes/src/__default.php:18331 
[0x00007f00b4ec20c0] match() /data/web/public/includes/src/__default.php:17865 
[0x00007f00b4ec1a98] dispatch() /data/web/public/includes/src/__default.php:20465 
[0x00007f00b4ec1908] run() /data/web/public/app/Mage.php:684 
[0x00007f00b4ec17f8] run() /data/web/public/index.php:87 

LSOF说:

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 
php5-fpm 24259 app 10uW REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 
php5-fpm 24262 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 
php5-fpm 24351 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 
php5-fpm 24357 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 
php5-fpm 24358 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 
php5-fpm 25563 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 
php5-fpm 25564 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 

根据strace的,所有这些过程都在等待羊群(LOCK_EX),即使是在上面的lsof输出中具有W标志的人也是如此。

此事件中的CPU占用率接近0

那么,为什么第一session_start窍门,即使它现在似乎有了会话文件的写锁?我怎么能进一步调试呢?

这是一个名为“race condition with ajax and php sessions”的讨论。事实上,引发上述问题的请求都是一致的AJAX调用。但是,本文指出:

如果您使用过PHP的内置默认会话处理(使用 文件),您将永远不会遇到问题。

所以目前我不知道下一步该去哪里。

+1

之前,我开始思考:该死的好问题!编辑:思考后:我很无能。 – MoshMage 2014-09-24 13:08:16

+1

每月一次?事件发生在同一天和同一时间吗? – 2014-09-24 13:42:20

+0

坏盘?这将是一个很难调试。 – Brad 2014-09-24 13:48:20

回答

0

在你的Ajax调用中,我猜你在那个文件中有session_start和你的/ tmp目录中的某个地方,你的ubuntu php正在保存它的会话。为了解决你的问题,你需要对这些脚本运行负载测试,它也可能是数据库,可能是你无法用肉眼看到的一个因素。

尝试这样:http://smartbear.com/products/qa-tools/load-testing-tool/ajax-load-testing/作为一个试验,也许你可以得到的问题的底部。您还需要深入探讨有关此问题的会话,包括使用ajax调用的单个文件。

您应该设置某些类型的性能测试,以针对发生问题时可以运行的后端调用。这些图层是PHP,PHP-FPM,Magento,我猜猜MySQL,Ubuntu,网络连接和Apache?

+0

也看这个:http://smartbear.com/products/qa-tools/load-testing-tool/load-testing-metrics/您需要工具和一些类型的指标来比较 – unixmiah 2014-09-24 18:47:45

0

当您有一个导入脚本需要很长时间才能执行时,浏览器似乎锁定,您无法再访问该网站。这是因为请求正在读取和锁定会话文件以防止损坏。

您可以 - 使用不同的会话处理程序与一下session_set_save_handler() - 使用session_write_close()在导入脚本,一旦你不需要再会话(最好的时刻是之前刚长时部分发生) ,如果导入脚本需要更改会话变量,则可以随时随地使用session_start,并尽可能多次使用它。

http://php.net/manual/en/function.session-start.php

0

我会建议检查会话表上的Magento ... 是因为它存储有你的数据库,你可能有一个问题,在一个MySQL表会话...

0

我发现最好将会话存储在本地磁盘上而不是数据库中。

创建一个在根目录下名为“会话”目录,然后把所有的会话通过将以下代码脚本的顶部写有你所说的“在session_start()”

$session_path = $_SERVER['DOCUMENT_ROOT']; //this session path assumes you are not using a subdomain 
ini_set('session.save_path', $session_path.'/sessions/'); 
权利之前

从文件加载比从数据库加载更快。和PHP管理它一样,所以我选择速度。

1

未知的东西阻塞了第一个剧本,它阻挡了休息。

PHP保持对写开放的会议文件,直到脚本结束后。这意味着如果一个脚本卡住了,或者执行得很慢,所有其他依赖于会话的请求都会被阻塞,直到完成。

两个最好的做法 - 直到你需要它不启动会议,并明确结束与session_write_close()当你做改变的,尤其是做一些缓慢的或潜在的越野车前的会议。

那么你只有1个卡住过程,而不是锁定用户。

0

一个很好的做法是安装memecached为PHP,然后就设置这些值:

session.save_handler = memcache 
session.save_path = “tcp://127.0.0.1:11211″ 
相关问题