Długotrwałe żądania strony administracyjnej Blokowanie innych żądań


17

Jeśli zaloguję się do backendu Magento i wykonam jakieś zadanie, które zajmuje dużo czasu (globalne wyszukiwanie w dużych katalogach, długo działający przepływ danych itp.), Moja przeglądarka internetowa odmówi załadowania innych stron administracyjnych tylko w tej przeglądarce . Dlaczego tak się dzieje i czy istnieje jakakolwiek znana metoda obejścia tego problemu?

To znaczy, jeśli ja

  1. Zaloguj się na stronie pulpitu Magento

  2. Otwórz drugą kartę z dowolną stroną administracyjną Magento

  3. Wykonaj długo działające wyszukiwanie globalne (symulowane wywołaniem sleep(30)na początku globalSearchAction) w pierwszej zakładce

  4. Spróbuj ponownie załadować drugą kartę

Oczekiwane zachowanie: Druga karta natychmiast ładuje zawartość strony

Rzeczywiste zachowanie: druga karta ładuje się dopiero po zakończeniu długotrwałego wyszukiwania globalnego

Czy ktoś wie, dlaczego tak się dzieje? (Domyślam się, że żądania konsoli administracyjnej Magento blokują jakiś zasób, którego Magento potrzebuje do uruchomienia, ale nie wiem co to jest)

Czy ktoś wie o poprawce / obejściu?


1
Pan wysłał mnie właśnie na wyzwanie! :)
davidalger

Odpowiedzi:


21

Problem jest spowodowany blokadą umieszczoną przez moduł obsługi sesji PHP. Więc to nie Magento jawnie coś blokuje i próbuje blokować żądania administratora, ale prawie efekt uboczny per se przechowywania pamięci sesji.

Blokada zapisu jest umieszczony w pliku danych sesji, gdy jest on otwarty przez początkowe (długo pracuje) żądanie, powodując drugą prośbę do bloku, aż blokada zostanie zwolniona, gdy nazywa session_startsięMage_Core_Model_Session_Abstract_Varien::start

Jest to w 100% powtarzalne. Użyłem tej samej metody, co ty, dodając sleep(30)do góryMage_Adminhtml_IndexController::globalSearchAction

Warto zauważyć, że nie można tego odtworzyć, jeśli używasz pamięci sesji db. Po znalezieniu głównej przyczyny ustawiłem piaskownicę na przechowywanie sesji db i nie mogłem już odtworzyć problemu. Więc programy obsługi sesji db Magento najwyraźniej nie używają blokowania na poziomie wiersza do blokowania zapisów sesji. Uważam to za interesujące, ponieważ może powodować utratę danych sesji, ponieważ aplikacja oczywiście nie rozlicza wielu wątków zapisujących do tej samej sesji. Uwaga dla czytelników: nigdy nie używałbym pamięci sesji sesji db w produkcji, aby spróbować rozwiązać ten problem, jest to dobre tylko do przeciążania bazy danych MySql.

Nie próbowałem odtworzyć tego zachowania przy użyciu systemów pamięci sesji opartych na pamięci, takich jak Redis, ale zgaduję, że blokowanie rekordów w sklepie sesji prawdopodobnie zostało w nich przeoczone.

Istnieją techniki, które można zastosować, aby tego uniknąć, np. session_write_closeZwolnienie blokady przed rozpoczęciem długotrwałej pracy. Ale to również uniemożliwi Ci pisanie na sesję, ponieważ właśnie ją zamknąłeś. Tak więc prawdopodobnie nie będzie łatwo zaimplementować go w Magento, ale potencjalnie może zostać zaimplementowany na określonych trasach / kontrolerach.

Moją techniką przypisywania tego jako głównej przyczyny było włączenie profilera Xdebug i sprawdzenie pliku „cachegrind”. Po zakończeniu drugiego żądania załadowałem plik wyjściowy (~ 25 MB dziennika) do MacCallGrind i zagłębiłem się w ślad zgodnie ze ścieżką wywołań, gdzie czas włączenia wynosił 28 sekund lub więcej. To ostatecznie doprowadziło mnie do session_startrozmowy, która zajęła ~ 28 sekund, co dało mi świetny punkt do zbadania.

EDYCJA: Dla zainteresowanych zamieściłem zrzut ekranu pliku „cachegrind” oglądanego w MacCallGrind na Twitterze.


Moduł uRapidFlow firmy Unirgy zamyka sesję, aby uniknąć tego problemu, co jest miłe w pewnym sensie, ale jest frustrujące, ponieważ utrudnia przekazywanie opinii użytkownikowi.
Peter O'Callaghan

@davidalger - Jaką pamięć sesji zazwyczaj wdrażasz dla witryn klienckich?
Alan Storm,

3
Re: blokowanie pliku sesji PHP, jest to mniej ważne dla integralności danych niż dla integralności samego pliku na dysku. Posiadanie wielu procesów otwierania i zapisywania bitów na dysku (jakim jest plik) szybko doprowadzi do uszkodzenia danych. MySQL, redis i większość baz danych zostały zaprojektowane specjalnie, aby zachować spójność, nawet jeśli istnieje wiele zapisów w tym samym czasie. tzn. nie chodzi o to, że blokowanie zostało przeoczone, ale o to, że nie jest tak bardzo potrzebne.
Alan Storm,

@AlanStorm - dedykowana instancja Memcached dla instalacji z równoważeniem obciążenia, system plików dla klastrów pojedynczych aplikacji. System plików działa najlepiej tam, gdzie nie ma wielu węzłów, ponieważ nie ma opóźnienia IP.
davidalger

Prawidłowe zablokowanie pliku polega na zapobieganiu uszkodzeniu danych. Jednak przytrzymanie blokady do czasu zamknięcia sesji zapobiega utracie danych. Jeśli dwa procesy załadują dane sesji, zmodyfikuj je, a następnie wypisz, jeden z nich zostanie zastąpiony modyfikacjami. Zasadniczo nie będzie stanowić poważnego problemu, ale może spowodować utratę danych i / lub nieprzyjemne problemy z debugowaniem.
davidalger
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.