Opiekuję się sklepem Magento z 400-500 odwiedzających i 40-50 zamówień dziennie. Ostatnio system został zaktualizowany z Magento EE 1.14.2.4 do Magento EE 1.14.3.2 i zauważyłem dziwne wyjątki w logach:
exception 'Mage_Core_Model_Session_Exception' in
/var/www/.../app/code/core/Mage/Core/Model/Session/Abstract/Varien.php:418
Goniłem ten wyjątek i wiem, że jest on uruchamiany, ponieważ następujący kod sprawdzania poprawności sesji nie sprawdza poprawności sesji:
class Mage_Core_Model_Session_Abstract_Varien extends Varien_Object
{
// ...
protected function _validate()
{
// ...
if ($this->useValidateSessionExpire()
&& isset($sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP])
&& $sessionData[self::VALIDATOR_SESSION_EXPIRE_TIMESTAMP] < time() ) {
Ten if-block został dodany do pliku z najnowszą wersją Magento. I to najwyraźniej zmiana hamowania, zobacz więcej szczegółów poniżej.
Wyjątek zdarza się dość często, kilkanaście razy dziennie. ale nie jestem w stanie odtworzyć warunków, które prowadzą do wyjątku, chyba że dosłownie spełnię powyższy warunek. Wyjątki najczęściej występują na stronach ze szczegółowymi informacjami o produkcie i na ostatnim etapie realizacji jednej strony. Sklep jest sklepem b2b, użytkownik musi być zalogowany, aby zobaczyć stronę produktu lub aby móc dokonać zakupu, oznacza to, że użytkownik zostaje przekierowany na strony logowania, gdy sesja zostanie unieważniona / wygasła. W tej chwili ważniejsze jest dla mnie rozwiązanie tego problemu podczas realizacji transakcji.
Co dzieje się z perspektywy użytkownika: Użytkownik wypełnia koszyk, przechodzi do kasy i osiąga ostatni krok, a następnie naciska przycisk „Prześlij zamówienie” i nic się nie dzieje. Za kulisami JS Magento wykonuje żądanie AJAX i JS spodziewa się otrzymać JSON z powrotem, ale jeśli ten błąd się zdarzy, zostanie zwrócony kod HTML strony logowania, który nie może zostać przeanalizowany przez JavaScript i po prostu nic nie robi. To jest bardzo mylące dla użytkowników.
Cóż, to nie jest kompletny scenariusz dla użytkowników, skontaktowaliśmy się z użytkownikami i powiedzieli nam, że czekali kilka dni między wypełnieniem koszyka a złożeniem zamówienia, co dokładnie oznacza, że trudno to zrozumieć, ponieważ ludzie po prostu tego nie pamiętają.
Żywotność sesji PHP - 350000 (~ 4 dni w sekundach) Żywotność plików cookie - 345600 (4 dni)
Oto aktualne pytanie: jak mogę dowiedzieć się, jakie zachowanie użytkownika prowadzi do wyjątku?
AKTUALIZACJA Jak dotąd wiem, że ten wyjątek zdarza się w następnych klasach zgodnie z otrzymanym żądaniem, co dla mnie nie znaczy nic.
/catalogsearch/result/?q=… Mage_Core_Model_Session
/checkout/cart/ Mage_Core_Model_Session
/checkout/onepage/saveOrder/… Mage_Rss_Model_Session
/customer/account/loginPost/ Mage_Core_Model_Session
/customer/account/loginPost/ Mage_Reports_Model_Session
/customer/account/logout/ Mage_Reports_Model_Session
/catalog/product/view/… Mage_Reports_Model_Session
/catalog/product/view/… Mage_Tag_Model_Session
AKTUALIZACJA 2 : sesje są przechowywane w plikach i czyszczone przez moduł czyszczący sesje PHP, niezależnie od tego, czy jest to dobry wybór, czy nie, nie wchodzi w zakres tego pytania.
źródło
Odpowiedzi:
Po zaawansowanym debugowaniu, śledzeniu sesji i przemyśleniu całej tej magii udało mi się odtworzyć problem i zrozumieć jego przyczynę. Przygotowałem małą ilustrację czasową, którą możesz zobaczyć poniżej.
/sales/order/save/...
żądanie)Oto jak odtworzyć:
Powód:
Istnieją pewne sesje, które są tworzone tylko na podstawie określonych żądań, np. Są tworzone
Mage_Rss_Model_Session
tylko podczas faktycznego finalizowania transakcji, a nie podczas przeglądania katalogu. Jednocześnie znacznik czasu wygaśnięcia sesji jest ustawiany tylko wtedy, gdy sesja została utworzona. Oznacza to, że jeśli między dwiema kasami było wystarczająco dużo czasu, a sesja nie została zabita w międzyczasie (ponieważ użytkownik wylogował się lub plik cookie wygasł), nowy kod Magento uzna tę sesję za niepotwierdzoną i zwróci wyjątek, co wydaje się dziwne mnie.Jak naprawić:
Mam kilka opcji:
Jak to wymyśliłem:
Zacząłem od dodania następującego kodu do oryginalnego kodu
Mage_Core_Model_Session_Abstract_Varien
dało mi to dobry wgląd w klasy, których dotyczy problem, ich korelację i ile sesji upłynęło. Ale to nie wyjaśniało, dlaczego tak się dzieje i jakie działania użytkownika prowadzą do problemu.
Potem zacząłem zastanawiać się, jak mogę prześledzić wszystkie zmiany danych sesji i natknąłem się na to pytanie /superuser/368231/automatic-versioning-upon-file-change-modify-create-delete, które postanowiłem podać próba
git
iincron
kombinacja, ale po zaimplementowaniu go i przetestowaniu w piaskownicy zdałem sobie sprawę, że zabraknie mi miejsca na dysku w produkcji bardzo szybko.Postanowiłem zbudować mały skrypt PHP, który dekoduje dane sesji i zapisuje logi dla każdej sesji. Ten skrypt został wywołany przez
incron
a oto odpowiedni
incrontab
wpispróbka wyjściowa
PS:
Aktualne wersje obu
nie są w stanie obsłużyć powyższego wyjątku podczas żądania AJAX. Nie wyświetlają dosłownie nic użytkownikowi, a użytkownik zostaje skutecznie wylogowany!
PPS:
najwyraźniej dotyczy to również wersji Magento CE 1.9.3.x, patrz https://github.com/OpenMage/magento-mirror/blame/magento-1.9/app/code/core/Mage/Core/Model/Session/Abstract/ Varien.php
PPPS:
Kiedy powiedziałem „Tymczasem usuń ten kod”. Miałem na myśli wyłączenie następującego bloku
możesz to zrobić na wiele sposobów, w tym:
$this->useValidateSessionExpire()
return trueźródło
<Mage_Rss>
i to naprawiło problem (tymczasowa poprawka) i złożyłem bilet z obsługą Magento.Kolejny sposób, aby to naprawić (i poprawić sprawdzanie poprawności sesji)
ColinM @ https://github.com/OpenMage/magento-lts
Źródło: https://github.com/OpenMage/magento-lts/commit/de06e671c09b375605a956e100911396822e276a
Aktualizacja:
Napraw
web/session/use_http_x_forwarded_for option
opcję wyłączoną ... https://github.com/OpenMage/magento-lts/pull/457/commits/ec8128b4605e82406679c3cd81244ddf3878c379źródło
Jak przechowujesz sesje? (tj. w var / session / lub w DB, lub przy użyciu innych mechanizmów buforowania, takich jak Redis lub Memcached)
Niezależnie od tego, którego używasz, upewnij się, że Twoje uprawnienia do zapisu są prawidłowe
var/session/
(zwykle ustawione na 755 dla katalogów i 644 dla plików), lub jeśli używasz Redis lub Memcache, upewnij się, że ustawienia połączenia i limitu czasu są odpowiednie dla tych .Inchoo ma dobry samouczek dla Redis: http://inchoo.net/magento/using-redis-cache-backend-and-session-storage-in-magento/
Jeśli korzystasz z Memcache, zapoznaj się z tym artykułem (odwołuje się do wersji 1.10, ale nie powinno się znacznie różnić): http://www.magestore.com/magento/magento-sessions-disappearing-w-memcache-turned-on.html
Ponadto, jeśli zdarza się, że używasz czegoś takiego jak Lakier, w przeszłości występowały problemy z sesjami, w których potrzebne były dziurkowanie niektórych stron.
Wreszcie, jeśli używasz systemu plików do sesji, możesz znaleźć ulgę, po prostu przełączając
<session_save>
węzełlocal.xml
na „db” zamiast „pliki”.Od tego
<session_save><![CDATA[files]]></session_save>
Do tego
<session_save><![CDATA[db]]></session_save>
źródło
Szczegół Antoniego Boritskiego jest fantastyczny. Ale zamiast wykluczyć ten blok, możesz zrobić kopię lokalną, aby nie edytować rdzenia i przepisać blok w następujący sposób:
Zapewnia to, że porównanie między time () i znacznikiem_czasu sesji jest wykonywane tylko wtedy, gdy klucz istnieje, a gdy zostanie znaleziona sesja, która nie ma klucza (tj. Sesja wcześniejsza niż 1.9.3), klucz zostanie dodany.
źródło