2014-09-24 5 views
6

NB Dies ist nicht ein Betrüger von PHP session_start() causing HTTP requests to hang (und andere ähnlich genannten Fragen zu SO), wie mein Fall ist gelegentlich, nicht dauerhaft.Warum hängt PHP gelegentlich auf session_start()

Verwendung Ubuntu 12.04,Magento, PHP-FPM (5.4) und Standard-PHP-Session-Handler (mit Dateien auf ext4).

Übrigens (once per month) alle PHP-Prozesse auf session_start() hängen (nach 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 sagt:

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 

Nach strace, all diese Prozesse warten auf Herde (LOCK_EX), sogar derjenige, der das W-Flag in der obigen Ausgabe hat.

Die CPU-Auslastung während dieses Vorfalls ist in der Nähe von 0.

Warum also der ersten session_start hängen, auch wenn es eine Schreibsperre auf der Sitzungsdatei erworben zu haben scheint? Wie könnte ich das weiter debuggen?

Hier ist eine Diskussion namens "race condition with ajax and php sessions". In der Tat sind die Anfragen, die das obige Problem auslösen, konsistent AJAX-Anrufe. Allerdings heißt es in diesem Artikel, dass:

Wenn Sie PHP eingebaut, Standard-Session Handling verwendet haben (das verwendet -Dateien), die Sie nie über das Problem kommen.

Also momentan bin ich ratlos, wo ich als nächstes suchen soll.

+1

Bevor ich anfangen zu denken: DAMN gute Frage! edit: Nach dem Nachdenken: Ich bin ahnungslos. – MoshMage

+1

Einmal im Monat? Ist das Vorkommen regelmäßig, am selben Tag und zur gleichen Zeit? –

+0

Schlechte Festplatte? Das wird schwer zu debuggen sein. – Brad

Antwort

0

Auf Ihre Ajax-Anrufe Ich rate in dieser Datei haben Sie session_start und irgendwo in Ihrem/Tmp-Verzeichnis in Ihrem Ubuntu speichert PHP seine Sitzungen. Um Ihr Problem zu lösen, müssen Sie Load-Tests mit diesen Skripten durchführen. Es kann auch die DB sein, die ein Faktor sein kann, den Sie mit bloßem Auge nicht sehen können.

Versuchen Sie etwas wie das: http://smartbear.com/products/qa-tools/load-testing-tool/ajax-load-testing/ als eine Probe vielleicht können Sie auf das Ende des Problems. Sie müssen auch tiefer in die Sitzungen für diese Angelegenheit einschließlich der einzelnen Dateien, die Ajax Anrufe verwendet graben.

Sie sollten eine Art von Leistungstest für diese Aufrufe an das Back-End einrichten, die Sie ausführen können, wenn das Problem auftritt. Die Ebenen sind PHP, PHP-FPM, Magento, MySQL, Ubuntu, Netzwerkverbindung und Apache?

+0

siehe auch: http://smartbear.com/products/qa-tools/load-testing-tool/load-testing-metrics/ Sie benötigen Tools und einige Arten von Metriken zum Vergleich – unixmiah

0

Wenn Sie ein Import-Skript haben, das lange dauert, scheint der Browser zu sperren und Sie können nicht mehr auf die Website zugreifen. Dies liegt daran, dass eine Anforderung die Sitzungsdatei liest und sperrt, um eine Beschädigung zu verhindern.

Sie kann entweder - einen anderen Session-Handler mit session_set_save_handler() verwendet - Verwendung session_write_close() im Importskript, sobald Sie brauchen Sitzung nicht mehr (bester Moment ist kurz vor der lang während eines Teil stattfindet) Sie können session_start wann immer Sie wollen und so oft Sie möchten, wenn Ihr Import-Skript erfordert, dass Sitzungsvariablen geändert werden.

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

0

Ich würde empfehlen den Sitzungen Tabelle auf magento zu überprüfen ... da es Sitzungen auf einem MySQL-Tabelle speichert Sie ein Problem mit Ihrem db ...

0

kann ich es finden am besten um Sitzungen auf einer lokalen Festplatte und nicht in der Datenbank zu speichern.

Erstellen Sie ein Verzeichnis namens ‚Sitzungen‘ im Stammverzeichnis, und dann haben alle Ihre Sitzungen dort schreiben, indem Sie den folgenden Code an der Spitze von Skripten setzen rechts, bevor Sie „session_start()“ nennen

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

Laden von Datei ist schneller als Laden von einer Datenbank. Und php schafft es trotzdem, also wähle ich Geschwindigkeit.

1

Etwas unbekannt blockiert das erste Skript, und es blockiert den Rest.

PHP hält die Sitzungsdatei zum Schreiben offen, bis das Skript beendet ist. Das heißt, wenn ein Skript nicht mehr reagiert oder etwas verlangsamt, werden alle anderen von der Sitzung abhängigen Anfragen blockiert, bis sie beendet sind.

Zwei bewährte Vorgehensweisen: Starten Sie die Sitzung erst, wenn Sie sie benötigen, und beenden Sie die Sitzung explizit mit session_write_close(), wenn Sie sie geändert haben, insbesondere bevor Sie etwas langsames oder möglicherweise fehlerhaftes Programm ausführen.

Dann haben Sie nur 1 stecken Prozess statt eines gesperrten Benutzer.

0

Eine gute Praxis ist für PHP installieren memecached und legen Sie dann nur diese Werte:

session.save_handler = memcache 
session.save_path = “tcp://127.0.0.1:11211″ 
Verwandte Themen