2014-09-24 71 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″ 
相關問題