Estou cuidando de uma loja Magento com 400 a 500 visitantes e 40 a 50 pedidos por dia. Recentemente, o sistema foi atualizado do Magento EE 1.14.2.4 para o Magento EE 1.14.3.2 e notei algumas exceções estranhas nos logs:
exception 'Mage_Core_Model_Session_Exception' in
/var/www/.../app/code/core/Mage/Core/Model/Session/Abstract/Varien.php:418
Eu estava perseguindo essa exceção e sei que ela está sendo acionada porque o seguinte código de validação da sessão falha ao validar a sessão:
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() ) {
Este bloco if foi adicionado ao arquivo com a versão mais recente do Magento. E esta é uma mudança de frenagem, aparentemente, veja mais detalhes abaixo.
A exceção está acontecendo com bastante frequência, como uma dúzia de vezes por dia. mas não consigo recriar condições que levam à exceção, a menos que eu literalmente aplique a condição acima. As exceções costumam ocorrer nas páginas de detalhes do produto e na última etapa do checkout de uma página. A loja é uma loja b2b, o usuário deve estar logado para ver a página do produto ou para fazer o checkout, significa que o usuário é redirecionado para as páginas de login quando a sessão é invalidada / expirada. No momento, é mais importante para mim corrigir esse problema durante o checkout.
O que acontece da perspectiva do usuário: O usuário preenche o carrinho, faz o checkout e alcança o último passo, depois pressiona o botão "enviar o pedido" e nada acontece. Nos bastidores, o JS do Magento realiza uma solicitação AJAX e o JS espera receber o JSON de volta, mas se esse erro ocorrer, o HTML da página de login será retornado, o que não pode ser analisado pelo JavaScript e simplesmente não faz nada. Isso é super confuso para os usuários.
Bem, esse não é o cenário completo do usuário, contatamos os usuários e eles nos disseram que esperavam alguns dias entre encher o carrinho e enviar o pedido, o que isso significa exatamente é difícil de entender, porque as pessoas simplesmente não se lembram disso.
Duração da sessão do PHP - 350000 (~ 4 dias em segundos) Tempo de vida do cookie - 345600 (4 dias)
Aqui está a pergunta real: como descobrir que tipo de comportamento do usuário leva à exceção?
ATUALIZAÇÃO Até agora eu sei que a exceção acontece nas aulas seguintes, de acordo com a solicitação feita, para mim isso infelizmente não significa nada.
/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
ATUALIZAÇÃO 2 : as sessões são armazenadas em arquivos e limpas pelo coletor de lixo da sessão do PHP, se essa é uma boa opção ou não, está fora do escopo desta pergunta.
fonte
Respostas:
Depois de alguma depuração avançada, rastreamento de sessão e reflexão sobre toda essa mágica, consegui reproduzir o problema e entender o motivo. Eu preparei uma pequena ilustração de tempo, você pode ver abaixo.
/sales/order/save/...
solicitação)Aqui está como reproduzir:
Razão:
Há certas sessões que são instanciadas apenas em determinadas solicitações, por exemplo,
Mage_Rss_Model_Session
são instanciadas apenas durante o checkout real e não durante a navegação no catálogo. Ao mesmo tempo, o registro de data e hora de expiração da sessão é definido apenas quando a sessão foi instanciada. Isso significa que, se houver tempo suficiente entre dois checkouts e a sessão não for interrompida (porque o usuário desconectou ou o cookie expirou), o novo código Magento considerará essa sessão como não passando na validação e lançará uma exceção, o que parece estranho para mim.Como consertar:
Bem, eu tenho algumas opções:
Como eu descobri isso:
Comecei adicionando o seguinte ao código original de
Mage_Core_Model_Session_Abstract_Varien
isso me deu uma boa visão sobre as classes afetadas e sua correlação e quanto da sessão expirou. Mas isso não explicava por que isso acontece e quais ações do usuário levam ao problema.
Então comecei a pensar em como rastrear todas as alterações nos dados da sessão e me deparei com esta pergunta /superuser/368231/automatic-versioning-upon-file-change-modify-create-delete que decidi dar uma tentativa
git
eincron
combinação, mas depois de implementá-lo e testá-lo na sandbox, percebi que o espaço em disco ficaria muito rápido na produção.Decidi construir um pequeno script PHP que decodificaria os dados da sessão e gravaria logs para cada sessão. Este script foi chamado por
incron
e aqui está a
incrontab
entrada correspondentesaída de amostra
PS:
Versões atuais de ambos
não conseguem lidar com a exceção acima durante a solicitação AJAX. Eles exibem literalmente nada para o usuário, enquanto o usuário efetivamente é desconectado!
PPS:
aparentemente as versões do Magento CE 1.9.3.x também são afetadas, consulte https://github.com/OpenMage/magento-mirror/blame/magento-1.9/app/code/core/Mage/Core/Model/Session/Abstract/ Varien.php
PPPS:
Quando eu disse "Remova esse código enquanto isso". Eu quis dizer excluir o seguinte bloco
você pode fazer isso de várias maneiras, incluindo:
$this->useValidateSessionExpire()
retorno verdadeirofonte
<Mage_Rss>
e isso corrigiu o problema (correção temporária) e apresentou o tíquete com suporte ao magento.Outra maneira de corrigir isso (e melhorar a validação da sessão)
ColinM @ https://github.com/OpenMage/magento-lts
Fonte: https://github.com/OpenMage/magento-lts/commit/de06e671c09b375605a956e100911396822e276a
Atualizar:
Correção para a
web/session/use_http_x_forwarded_for option
opção desativada ... https://github.com/OpenMage/magento-lts/pull/457/commits/ec8128b4605e82406679c3cd81244ddf3878c379fonte
Como você está armazenando sessões? (ou seja, em var / session / ou no DB, ou usando outros mecanismos de armazenamento em cache, como Redis ou Memcached)
Qualquer que seja o seu uso, verifique se as permissões de gravação estão corretas
var/session/
(normalmente definidas como 755 para diretórios e 644 para arquivos) ou, se você estiver usando Redis ou Memcache, verifique se as configurações de conexão e tempo limite são boas para aqueles .O Inchoo tem um bom tutorial para Redis: http://inchoo.net/magento/using-redis-cache-backend-and-session-storage-in-magento/
Se estiver usando o Memcache, consulte este artigo (ele faz referência à v1.10, mas não deve ser muito diferente): http://www.magestore.com/magento/magento-sessions-disappearing-with-memcache-turned-on.html
Além disso, se você estiver usando algo como o Varnish, houve problemas no passado com sessões em que certas páginas eram necessárias.
Finalmente, se você estiver usando o sistema de arquivos para suas sessões, poderá encontrar alívio simplesmente alternando o
<session_save>
nó no seulocal.xml
para "db" em vez de "arquivos".A partir disso
<session_save><![CDATA[files]]></session_save>
Para isso
<session_save><![CDATA[db]]></session_save>
fonte
Os detalhes de Anton Boritskiy são fantásticos. Mas, em vez de excluir esse bloco, você pode fazer uma cópia local para não editar o núcleo e reescrever o bloco como:
Isso garante que a comparação entre time () e o session_expire_timestamp seja executada apenas quando a chave existir e que, quando for encontrada uma sessão que não possua a chave (ou seja, uma sessão anterior à 1.9.3), a chave será adicionada.
fonte