Das Problem wird durch eine Sperre des PHP-Session-Handlers verursacht. Es ist also nicht Magento, das explizit etwas sperrt und versucht, Administratoranforderungen zu blockieren, sondern fast ein Nebeneffekt des dateibasierten Sitzungsspeichers.
Eine Schreibsperre wird auf der Sitzungsdaten - Datei platziert , wenn es von der anfänglichen (Langlauf) Anforderung geöffnet wird, wodurch die zweite Anfrage nach Block , bis die Sperre gelöst wird , wenn es ruft session_start
inMage_Core_Model_Session_Abstract_Varien::start
Dies ist zu 100% reproduzierbar. Ich habe die gleiche Methode angewendet, die Sie angewendet haben, indem ich sleep(30)
oben ein hinzugefügt habeMage_Adminhtml_IndexController::globalSearchAction
Beachten Sie, dass dies nicht reproduziert werden kann, wenn Sie den Datenbanksitzungsspeicher verwenden. Nachdem ich die Hauptursache gefunden hatte, stellte ich eine Sandbox auf Datenbanksitzungsspeicher ein und konnte das Problem nicht mehr reproduzieren. Die Datenbank-Session-Handler von Magento verwenden anscheinend keine Sperren auf Zeilenebene, um Session-Schreibvorgänge zu sperren. Ich finde das interessant, weil es das Potenzial für Sitzungsdatenverlust gibt, da die Anwendung offensichtlich nicht für mehrere Threads verantwortlich ist, die in dieselbe Sitzung schreiben. Hinweis für Leser: Ich würde in der Produktion niemals db session storage verwenden, um dieses Problem zu lösen. Es ist nur gut, um Ihre MySql-Datenbank zu überlasten.
Ich habe nicht versucht, das Verhalten mit speicherbasierten Sitzungsspeichersystemen wie Redis zu reproduzieren, aber ich vermute, dass das Sperren der Datensätze im Sitzungsspeicher wahrscheinlich auch hier übersehen wurde.
Es gibt Techniken, mit denen dies vermieden werden kann, z. B. session_write_close
das Aufheben der Sperre, bevor Sie einen langfristigen Auftrag ausführen. Dies würde Sie jedoch auch daran hindern, an die Sitzung zu schreiben, da Sie sie gerade geschlossen haben. Es ist daher nicht sehr wahrscheinlich, dass es in Magento allgemein implementiert werden kann, aber es kann möglicherweise auf bestimmten Routen / Controllern implementiert werden.
Meine Technik, um dies als Grundursache festzuhalten, bestand darin, den Xdebug-Profiler zu aktivieren und die "Cachegrind" -Datei zu untersuchen. Sobald die zweite Anforderung abgeschlossen war, lud ich die Ausgabedatei (ca. 25 MB Protokoll) in MacCallGrind und führte einen Drilldown in die Ablaufverfolgung auf dem Pfad der Aufrufe durch, bei denen die Einschlusszeit 28 Sekunden oder mehr betrug. Dies führte mich schließlich zu dem session_start
Anruf, dessen Ausführung ~ 28 Sekunden in Anspruch nahm, und gab mir einen großartigen Anhaltspunkt für die Recherche von.
BEARBEITEN: Für die Interessierten habe ich einen Screenshot der "Cachegrind" -Datei gepostet, die in MacCallGrind auf Twitter angezeigt wird.