Estoy cuidando una tienda de Magento con 400-500 visitantes y 40-50 pedidos por día. Recientemente, el sistema se actualizó de Magento EE 1.14.2.4 a Magento EE 1.14.3.2 y noté algunas excepciones extrañas en los registros:
exception 'Mage_Core_Model_Session_Exception' in
/var/www/.../app/code/core/Mage/Core/Model/Session/Abstract/Varien.php:418
Estaba persiguiendo esa excepción y sé que se está disparando porque el siguiente código de validación de sesión no valida la sesión:
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 if-block se agregó al archivo con la última versión de Magento. Y aparentemente este es un cambio de frenado, vea más detalles a continuación.
La excepción ocurre con bastante frecuencia, como una docena de veces al día. pero no puedo recrear condiciones que conducen a la excepción, a menos que literalmente ponga verdadero en la condición anterior. Las excepciones ocurren con mayor frecuencia en las páginas de detalles del producto y en el último paso del pago de una página. La tienda es una tienda b2b, el usuario debe iniciar sesión para ver la página del producto o para poder pagar, significa que el usuario es redirigido a las páginas de inicio de sesión cuando la sesión se invalida / expira. Por el momento, es más importante para mí solucionar este problema durante el pago.
Lo que sucede desde la perspectiva del usuario: el usuario llena el carrito, procede al pago y llega al último paso, luego presiona el botón "enviar el pedido" y no sucede nada. Detrás de escena, JS de Magento realiza una solicitud AJAX y JS espera recibir JSON nuevamente, pero si ocurre este error, se devuelve el HTML de la página de inicio de sesión, que JavaScript no puede analizar y simplemente no hace nada. Eso es súper confuso para los usuarios.
Bueno, ese no es el escenario completo del usuario, contactamos a los usuarios y nos dijeron que esperaron unos días entre llenar el carrito y enviar el pedido, lo que eso significa exactamente es difícil de entender, porque la gente simplemente no lo recuerda.
Duración de la sesión PHP: 350000 (~ 4 días en segundos) Duración de la cookie: 345600 (4 días)
Aquí está la pregunta real: ¿cómo puedo averiguar qué tipo de comportamiento del usuario conduce a la excepción?
ACTUALIZACIÓN Hasta ahora sé que la excepción ocurre en las siguientes clases de acuerdo con la solicitud realizada, para mí eso no significa nada desafortunadamente.
/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
ACTUALIZACIÓN 2 : las sesiones se almacenan en archivos y el recolector de basura de la sesión de PHP las limpia, ya sea que esta sea una buena opción o no, está fuera del alcance de esta pregunta.
fuente
Respuestas:
Después de una depuración avanzada, seguimiento de la sesión y pensar en toda esa magia, pude reproducir el problema y comprender la razón. He preparado una pequeña ilustración de sincronización, puedes verla a continuación.
/sales/order/save/...
solicitud)Aquí está cómo reproducir:
Razón:
Hay ciertas sesiones que solo se instancian en las solicitudes dadas, por ejemplo,
Mage_Rss_Model_Session
solo se instancia durante el pago real y no mientras se navega por el catálogo. Al mismo tiempo, la marca de tiempo de caducidad de la sesión solo se establece cuando se instancia la sesión. Eso significa que si hubo tiempo suficiente entre dos pagos y la sesión no se canceló mientras tanto (porque el usuario cerró la sesión o la cookie expiró), el nuevo código de Magento considerará que la sesión no pasa la validación y generará una excepción, lo que suena extraño de alguna manera yo.Como arreglar:
Bueno, tengo pocas opciones:
¿Cómo lo descubrí?
Comencé agregando lo siguiente al código original de
Mage_Core_Model_Session_Abstract_Varien
me dio una buena idea sobre las clases afectadas y su correlación y la cantidad de sesiones que expiraron. Pero eso no explicaba por qué sucede y qué acciones del usuario conducen al problema.
Luego comencé a pensar en cómo puedo rastrear todos los cambios en los datos de la sesión y encontré esta pregunta /superuser/368231/automatic-versioning-upon-file-change-modify-create-delete que decidí dar un intento
git
y unaincron
combinación, pero después de implementarlo y probarlo en sandbox, me di cuenta de que me quedaría sin espacio en disco muy rápido en producción.Decidí construir un pequeño script PHP que decodificará los datos de sesión y escribirá registros para cada sesión. Este script fue llamado por
incron
y aquí está la
incrontab
entrada correspondientesalida de muestra
PD:
Versiones actuales de ambos
no pueden manejar la excepción anterior durante la solicitud de AJAX. ¡Literalmente no muestran nada al usuario, mientras que el usuario se desconecta efectivamente!
PPS:
aparentemente las versiones de Magento CE 1.9.3.x también se ven afectadas, consulte https://github.com/OpenMage/magento-mirror/blame/magento-1.9/app/code/core/Mage/Core/Model/Session/Abstract/ Varien.php
PPPS:
Cuando dije "Eliminar este código mientras tanto". Me refería a excluir el siguiente bloque
Puedes hacerlo de muchas maneras, incluyendo:
$this->useValidateSessionExpire()
realidad el retornofuente
<Mage_Rss>
y eso solucionó el problema (solución temporal) y he presentado el ticket con soporte de magento.Otra forma de arreglar esto (y mejorar la validación de la sesión)
ColinM @ https://github.com/OpenMage/magento-lts
Fuente: https://github.com/OpenMage/magento-lts/commit/de06e671c09b375605a956e100911396822e276a
Actualizar:
Solución para la
web/session/use_http_x_forwarded_for option
opción deshabilitada ... https://github.com/OpenMage/magento-lts/pull/457/commits/ec8128b4605e82406679c3cd81244ddf3878c379fuente
¿Cómo estás almacenando las sesiones? (es decir, en var / session / o en la base de datos, o utilizando otros motores de almacenamiento en caché como Redis o Memcached)
Independientemente de lo que esté usando, asegúrese de que sus permisos de escritura sean correctos
var/session/
(generalmente configurados en 755 para directorios y 644 para archivos), o si está usando Redis o Memcache, asegúrese de que su conexión y la configuración de tiempo de espera sean buenos para esos .Inchoo tiene un buen tutorial para Redis: http://inchoo.net/magento/using-redis-cache-backend-and-session-storage-in-magento/
Si usa Memcache, consulte este artículo (hace referencia a v1.10, pero no debería ser muy diferente): http://www.magestore.com/magento/magento-sessions-disappearing-with-memcache-turned-on.html
Además, si está usando algo como el barniz, ha habido problemas en el pasado con sesiones en las que se necesitaban perforar ciertas páginas.
Finalmente, si está utilizando el sistema de archivos para sus sesiones, puede encontrar alivio simplemente cambiando el
<session_save>
nodo enlocal.xml
"db" en lugar de "archivos".De esto
<session_save><![CDATA[files]]></session_save>
A esto
<session_save><![CDATA[db]]></session_save>
fuente
El detalle de Anton Boritskiy es fantástico. Pero en lugar de excluir este bloque, puede hacer una copia local para no editar el núcleo y reescribir el bloque como:
Esto asegura que la comparación entre time () y session_expire_timestamp solo se ejecuta cuando existe la clave y que cuando se encuentra una sesión que no tiene la clave (es decir, una sesión anterior a 1.9.3), se agrega la clave.
fuente