Procedimientos recomendados para utilizar sesiones HTTP
En este tema se presentan los métodos recomendados para la implementación de las sesiones de HTTP.
- Habilitar la integración de seguridad para proteger las sesiones HTTP
Las sesiones HTTP se identifican mediante ID de sesión. Un ID de sesión es un número pseudo-aleatorio generado en el tiempo de ejecución. La piratería de sesiones es un ataque conocido a las sesiones HTTP, y se puede evitar si se obliga a todas las peticiones que viajan en la red a que se realicen con una conexión segura (esto es, HTTPS). Pero no todas las configuraciones en un entorno de cliente obligan a esta restricción, debido al efecto en el rendimiento de las conexiones SSL. Esta modalidad relajada hace que la sesión HTTP sea vulnerable a la piratería, y debido a esta vulnerabilidad, WebSphere Application Server tiene la opción de integrar estrictamente las sesiones HTTP y la seguridad de WebSphere Application Server. Habilite la seguridad en WebSphere Application Server para proteger las sesiones de manera que sólo los usuarios que han creado las sesiones puedan acceder a ellas.
- Liberar los objetos HttpSession mediante javax.servlet.http.HttpSession.invalidate() cuando haya terminado. Los objetos HttpSession se encuentran dentro del contenedor web hasta que se produce lo siguiente:
- La aplicación lo libere explícita y de forma programada utilizando el método javax.servlet.http.HttpSession.invalidate; con mucha frecuencia, la invalidación programática es parte de una función de salida de la aplicación.
- WebSphere Application Server destruye el HttpSession asignado cuando caduca (el valor predeterminado es de 1800 segundos o 30 minutos). WebSphere Application Server puede mantener sólo un número determinado de sesiones HTTP en la memoria según los valores de gestión de sesiones. Para las sesiones distribuidas, cuando la antememoria de la sesión ha alcanzado su tamaño máximo y se solicita una nueva sesión, el recurso de gestión de sesiones elimina de la antememoria la sesión que hace más tiempo que se ha utilizado para crear espacio para la nueva sesión.
- No intente guardar y volver a utilizar el objeto HttpSession fuera de cada servlet o archivo JSP.
El objeto HttpSession es una función de HttpRequest (sólo puede obtenerlo mediante el método req.getSession), y una copia de dicho objeto sólo es válida durante la duración del método service del servlet o el archivo JSP. No puede almacenar en la antememoria el objeto HttpSession y hacer referencia al mismo fuera del ámbito de un servlet o un archivo JSP.
- Implemente la interfaz java.io.Serializable cuando desarrolle nuevos objetos que se vayan a almacenar en la sesión HTTP.
Una clase se serializa cuando implementa la interfaz java.io.Serializable. Al implementar la interfaz java.io.Serializable el objeto se puede serializar correctamente cuando se utilizan sesiones distribuidas. Las clases que no implementan esta interfaz no tendrán sus estados serializados o deserializados. Por lo tanto, si una clase no implementa la interfaz serializable, la JVM no puede conservar su estado en una base de datos o en otra JVM. Todos los subtipos de una clase serializable son serializables. A continuación se muestra un ejemplo:
public class MyObject implements java.io.Serializable {...}
Asegúrese de que todos los objetos de la variable de instancia que no están marcados como temporales sean serializables. No puede colocar en antememoria un objeto que no es serializable.
De conformidad con la especificación del servlet Java™, el contenedor de servlets distribuidos debe crear una excepción IllegalArgumentException para los objetos cuando el contenedor no puede dar soporte al mecanismo necesario para la migración de la sesión que los almacena. Sólo se crea una excepción cuando se ha seleccionado distribuíble.
- Utilice <codeph>write frequency=END_OF_SERVICE</codeph> al habilitar la migración tras error del estado de sesión para evitar perder datos durante la migración tras error con una base de datos o WebSphere eXtreme Scale. La pérdida de datos se evita porque los datos de la sesión se almacenan en la base de datos o en la cuadrícula de datos al final de cada solicitud. Este comportamiento genera tiempos de solicitud más largo, lo que degrada el rendimiento.
- Asegúrese de que los objetos Java que añade a una sesión están en la variable classpath correcta.
Si añade objetos Java a una sesión, coloque los archivos de clases de dichos objetos en la vía de acceso a clases correcta (la vía de acceso a clases de la aplicación si comparte entre los módulos web de una aplicación de empresa, o la vía de acceso a clases del módulo web si comparte sesiones compatibles con el Servlet 2.2) o en el directorio que contiene los otros servlets utilizados en WebSphere Application Server. En el caso de un clúster de sesiones, esta acción se aplica a cada nodo del clúster.
Puesto que el objeto HttpSession es compartido por servlets a los que el usuario puede acceder, considere seguir un convenio de denominación en el ámbito del sitio para evitar conflictos.
- Evitar almacenar gráficos de objetos de gran tamaño en el objeto HttpSession.
En la mayoría de aplicaciones, cada servidor necesita sólo una fracción de los datos totales de la sesión. Sin embargo, al almacenar los datos en el objeto HttpSession como un único objeto de gran tamaño, una aplicación hace que el producto WebSphere los procese todos cada vez.
- Utilice la Afinidad de sesiones para conseguir un mayor número de coincidencias en memoria caché en WebSphere Application Server.
WebSphere Application Server tiene funciones en el plug-in de HTTP Server que sirven de ayuda para la afinidad de sesiones. El plug-in lee los datos de la cookie (o el URL codificado) del navegador y ayudará a dirigir la petición a la aplicación o el clon correspondiente, según la clave de sesión asignada. Estas funciones aumentan el uso de la memoria caché interna y disminuyen los aciertos de base de datos u otra instancia de WebSphere Application Server.
- Maximice el uso de la afinidad de sesiones y evite romper la afinidad.
Si se utiliza correctamente la afinidad de sesiones se puede mejorar el rendimiento de WebSphere Application Server. La afinidad de sesiones en el entorno WebSphere Application Server es un modo de maximizar la memoria caché interna de los objetos de sesión y disminuir el número de lecturas de la base de datos u otra instancia de WebSphere Application Server. La afinidad de sesiones funciona almacenando en la antememoria los objetos de sesión en la instancia de servidor de la aplicación con la que interactúa un usuario. Si la aplicación se despliega en varios servidores de un grupo de servidores, la aplicación puede dirigir al usuario a cualquiera de los servidores. Si el usuario comienza en el servidor1 y un poco más tarde pasa al servidor2, el servidor deberá escribir toda la información de sesiones en la ubicación externa, para que la instancia de servidor en la que se está ejecutando el servidor2 pueda leer la base de datos. Puede utilizar la afinidad de sesiones para que no se lea la base de datos. Con la afinidad de sesiones, el usuario comienza en el servidor1 la primera petición, a continuación, para cada petición posterior el usuario regresará directamente al servidor1. El servidor1 solamente tiene que buscar en la antememoria para obtener la información de la sesión. El servidor1 no realiza nunca una llamada a la base de datos de sesiones para obtener la información.
Si no rompe la afinidad de sesiones mejorará el rendimiento. Algunas sugerencias para evitar romper la afinidad de las sesiones son:- Combine todas las aplicaciones web en una sola instancia de servidor de aplicaciones, si es posible, y utilice el diseño o la clonación para proporcionar el soporte de sustitución por anomalía.
- Cree la sesión para la página de marcos, pero no cree sesiones para las páginas dentro del marco cuando utilice archivos JSP de marcos múltiples. (Consulte la descripción más adelante en este tema.)
- Siga estas directrices cuando utilice páginas de marcos múltiples:
- Cree una sesión en un marco solo, o antes de acceder a ningún conjunto de marcos. Por ejemplo, suponiendo que no hay ninguna sesión asociada con el navegador y que un usuario accede a un archivo JSP de marcos múltiples, el navegador emite peticiones simultáneas para los archivos JSP. Como las peticiones no forman parte de ninguna sesión, los archivos JSP terminan creando varias sesiones, y todas las cookies se envían al navegador. El navegador sólo reconoce la última cookie que llega. Por lo tanto, sólo el cliente puede recuperar la sesión asociada con la última cookie. Se recomienda crear una sesión antes de acceder a páginas de múltiples marcos que utilizan archivos JSP.
- Por omisión, los archivos JSP obtienen una HTTPSession que utiliza el método request.getSession(true). Por lo tanto, los archivos JSP crean por omisión una sesión nueva si no existe ninguna para el cliente. Cada página del navegador está realizando la petición de una nueva sesión, pero sólo se utiliza una sesión por instancia de navegador. Un desarrollador puede utilizar <% @ page session="false" %> para desactivar la creación automática de sesiones de los archivos JSP que no accedan a la sesión. A continuación, si la página necesita acceder a la información de sesiones, el desarrollador puede utilizar <%HttpSession session = javax.servlet.http.HttpServletRequest.getSession(false); %> para obtener la sesión ya existente que se creó con el archivo JSP de creación de sesiones original. Esta acción permite evitar que se rompa la afinidad de sesiones en la carga inicial de las páginas de marcos.
- Actualice los datos de sesiones utilizando sólo un marco. Cuando utilice conjuntos de marcos, las soluciones entran en el servidor HTTP simultáneamente. Se remienda modificar los datos de sesión dentro un marco solo, para que los cambios de sesión no sean alterados temporalmente por los cambios de sesión en el conjunto de marcos simultáneo.
- Evite utilizar archivos JSP de múltiples marcos en los que los marcos apunten a aplicaciones web diferentes. Esta acción tiene como resultado la pérdida de la sesión creada por otra aplicación web, ya que la cookie JSESSIONID de la primera aplicación web se altera temporalmente con la JSESSIONID creada por la segunda aplicación web.
- Proteja todas las páginas (no sólo algunas) cuando aplique seguridad a los servlets o los archivos JSP que utilizan sesiones con la integración de seguridad habilitada.
La seguridad y las sesiones no deben tener fisuras. No tiene ningún sentido proteger el acceso al estado de sesión de manera parcial. Cuando se habilita la integración de seguridad en el recurso de gestión de sesiones, se deben proteger o desproteger todos los recursos a partir de los cuales se crea o accede a una sesión. No se pueden combinar recursos protegidos y desprotegidos.
El problema que comporta proteger sólo un par de páginas es que las sesiones creadas en páginas seguras se crean bajo la identidad del usuario autenticado. Sólo el mismo usuario puede acceder a las sesiones en otras páginas protegidas. Para que estas sesiones no puedan ser utilizadas por usuarios no autorizados, no se puede acceder a ellas desde una página no segura. Cuando se produce una petición desde una página no segura, se niega el acceso y se genera un error UnauthorizedSessionRequestException. (UnauthorizedSessionRequestException es una excepción de tiempo de ejecución que se anota cronológicamente de forma automática.)
- Utilice la actualización manual y el método sync() o la grabación basada en tiempo en aplicaciones que leen datos de sesión y no se actualizan con mucha frecuencia.
Con END_OF_SERVICE como frecuencia de grabación, cada vez que una aplicación utiliza las sesiones y cada vez que se leen los datos o se graban en dicha sesión, se actualiza el campo de hora LastAccess. Si se utilizan sesiones de base de datos, se produce una nueva escritura en la base de datos. Esta actividad es un problema de rendimiento que se puede evitar si se utiliza la opción Actualización manual y se vuelve a grabar el registro en la base de datos sólo cuando se actualizan los valores de datos, no en cada lectura o escritura del registro.
Para utilizar la actualización manual, actívela en el servicio de gestión de sesiones. (Consulte las tablas anteriores para obtener información sobre la ubicación). Además, el código de la aplicación debe utilizar la clase com.ibm.websphere.servlet.session.IBMSession en vez de la HttpSession genérica. Dentro del objeto IBMSession existe un método de sincronización. Este método indica a WebSphere Application Server que debe escribir los datos en el objeto de sesión de la base de datos. Esta actividad permite al desarrollador mejorar el rendimiento general al hacer que la información de la sesión permanezca solamente cuando sea necesaria.
Nota: Una alternativa al uso de actualizaciones manuales es utilizar las actualizaciones periódicas para que persistan los datos en intervalos de tiempo diferentes. Esta acción da resultados similares al esquema de actualización manual. - Implemente las siguientes sugerencias para conseguir un gran rendimiento:
- Si las aplicaciones no cambian los datos de la sesión de manera frecuente, utilice la Actualización manual y la función de sincronización (o la actualización periódica) para que la información de la sesión persista de manera eficaz.
- Procure que la cantidad de datos almacenados en la sesión sea lo más pequeña posible. Con la facilidad de uso de las sesiones para mantener los datos, a veces se almacenan demasiados datos en los objetos de sesión. Determine el equilibrio correcto entre el almacenamiento de datos y el rendimiento para utilizar las sesiones de manera eficaz.
- Si utiliza sesiones de base de datos, utilice una base de datos dedicada para la base de datos de la sesión. Evite utilizar la base de datos de aplicaciones. Esto le ayudará a evitar la contención de las conexiones JDBC y le permite obtener un rendimiento mejor de la base de datos.
- Si utiliza sesiones de memoria a memoria, utilice particiones (réplica única o de grupo) cuando los clústeres aumenten de tamaño y disminuya la posibilidad de escalado.
- Verifique que tiene los fixpacks más recientes de WebSphere Application Server.
- Utilice las siguientes herramientas para supervisar el rendimiento de las
sesiones.
- Ejecute el servlet com.ibm.servlet.personalization.sessiontracking.IBMTrackerDebug. Para ejecutar este servlet, debe tener el invocador de servlets ejecutándose en la aplicación web desde la que desea ejecutar este servlet. O puede configurar de forma explícita este servlet en la aplicación que desea ejecutar.
- Utilice WebSphere Application Server, Resource Analyzer, que se suministra con el producto WebSphere Application Server, para supervisar las sesiones activas y las estadísticas del entorno WebSphere Application Server.
- Utilice herramientas de rastreo de base de datos como, por ejemplo, "Monitoring" en DB2. (Consulte la documentación correspondiente al sistema de base de datos utilizado).