Almacenamiento en memoria caché de fragmentos o páginas completas

El método mediante el cual WebSphere Application Server almacena en memoria caché los archivos JSP se basa en cómo se escriba la JSP. Si la salida de página para un mandato de HCL Commerce determinado produce siempre el mismo resultado basándose en los parámetros de URL y los atributos de petición, esta salida de página se puede almacenar en memoria caché con la entrada de memoria caché (cache-entry) utilizando el elemento de propiedad, consume-subfragments (CSF), junto con el servlet de controlador de HCL Commerce (com.ibm.commerce.struts.ECActionServlet.class en versión 9.0.0.x o com.ibm.commerce.struts.v2.ECActionServlet.class en versión 9.0.1+ y si está utilizando la configuración de Strut 2com.ibm.commerce.struts.v2.ECActionStrutsServlet.class) como nombre de servlet. Cuando la entrada de memoria caché (cache-entry) se define de esta manera, la salida de página se almacena en memoria caché según el método denominado almacenamiento en memoria caché de full page. La gran ventaja de utilizar consume-subfragments con el servlet de controlador es el rendimiento, pero si hay información personalizada en la página, por ejemplo un minicarro de la compra, se puede utilizar full page el almacenamiento en memoria caché con fragmentos.

Si la salida de página tiene secciones que son dependientes del usuario, la salida de página se almacena en memoria caché según el método denominado almacenamiento en memoria caché de fragment. Es decir, las páginas JSP se almacenan en memoria caché como entradas independientes de memoria caché y vuelven a juntarse cuando se las solicita. Para el almacenamiento en memoria caché de fragmentos (JSP), HCL Commerce tiene que ejecutar el mandato para determinar qué JSP se debe ejecutar antes de que el mecanismo de almacenamiento en memoria caché dinámica pueda determinar si la JSP puede servirse desde la memoria caché o no. La ventaja de este método es la flexibilidad, porque para formar una página pueden volver a juntarse diversas entradas de memoria caché, según la información de usuario.

En algunos casos resulta práctico impedir que determinados fragmentos se almacenen en memoria caché con una página entera. En lugar de almacenarse en memoria caché con la página completa full page, los fragmentos se almacenan en memoria caché de forma independiente. Por ejemplo, si hay un mensaje de bienvenida personalizado o una minipágina de pedidos actual, se utiliza la propiedad do-not-consume. La entrada padre se marca con la propiedad consume-subfragments y el fragmento hijo que contiene el área de personalización se marcará con esta propiedad do-not-consume. Con esta combinación, el aumento de rendimiento del almacenamiento en memoria caché de páginas completas permanece intacto para la página entera excluyendo el fragmento hijo que se almacena en memoria caché de forma independiente.

Almacenamiento en memoria caché de páginas completas

Cuando se utiliza el elemento de propiedad consume-subfragments (CSF), la entrada de memoria caché para la página padre (la que está marcada con CSF) incluirá todo el contenido de todos los fragmentos en la entrada de memoria caché, lo que produce una gran entrada de memoria caché que no tiene inclusiones o reenvíos, pero que, por otro lado, posee el contenido del árbol de entradas completo.

Cuando se almacena en memoria caché un servlet, solo se almacena el contenido de ese servlet. La memoria caché incluye espacios reservados para los demás fragmentos que incluye o reenvía. consume-subfragments (CSF) indica a la memoria caché que no pare de guardar el contenido cuando incluye un servlet hijo. La entrada padre (la que está marcada con CSF) incluirá todo el contenido de todos los fragmentos en su entrada de memoria caché, formando una gran entrada de memoria caché que no tiene includes ni forwards, sino el contenido de todo el árbol de entradas. Esto puede ahorrar una cantidad importante de proceso del servidor de aplicaciones, pero normalmente solo es útil cuando la solicitud HTTP externa contiene toda la información necesaria para determinar el árbol entero de los fragmentos incluidos.

Por ejemplo, si la <cache-entry> se define del modo siguiente:


<cache-entry>
  <class>servlet</class>
 
<name>strutsaction</name>
  <property name="consume-subfragments">true</property>
  <property name="save-attributes">false</property>
  <property name="store-cookies">false</property>

  <!-- StoreCatalogDisplay?storeId=<storeId> -->
  <cache-id>
     <component id="" type="pathinfo">
        <required>true</required>
           <value>/StoreCatalogDisplay</value>
     </component>
     <component id="storeId" type="parameter">
        <required>true</required>
     </component>
  </cache-id>
</cache-entry>

Donde strutsaction está com.ibm.commerce.struts.v2.ECActionServlet.class en HCL Commerce versiones 9.0.0.x, o com.ibm.commerce.struts.v2.ECActionServlet.class en versiones 9.0.1+ y si utiliza la configuración de Strut 2 com.ibm.commerce.struts.v2.ECActionStrutsServlet.class. Observe que cuando la propiedad save-attributes se establece en false, los atributos de la solicitud no se guardan con la entrada de memoria caché. Cuando la propiedad store-cookies se establece en false, las cookies de solicitud no se guardan con la entrada de memoria caché.

En el ejemplo anterior, la entrada del servlet de memoria caché contendrá un include utilizado de StoreCatalogDisplay.jsp que es el archivo JSP enviado por el mandato StoreCatalogDisplay.

Memoria caché de fragmentos

Para que un fragmento se pueda almacenar en memoria caché, es necesario que sea autoejecutable. Cada archivo JSP incluido dinámicamente tiene que tener su propio <cache-entry> definido en el archivo cachespec.xml para que la memoria caché dinámica le responda cuando reciba una solicitud. De lo contrario, cada archivo JSP incluido dinámicamente volverá a ejecutarse para cada petición. Por ejemplo, considere si StoreCatalogDisplay.jsp incluye CachedHeaderDisplay.jsp, CachedFooterDisplay.jsp y CachedStoreCatalogDisplay.jsp dinámicamente y solo configura un <cache-entry> para el archivo CachedStoreCatalogDisplay.jsp. A continuación, cuando solicite la página StoreCatalogDisplay, los archivos CachedStoreCatalogDisplay.jsp, CachedHeaderDisplay.jsp y CachedFooterDisplay.jsp se ejecutarán si no se almacenan en memoria caché. A continuación se muestra un ejemplo de cómo definir <cache-entry> para CachedStoreCatalogDisplay.jsp:


<cache-entry>
  <class>servlet</class>
 
<name>/AdvancedB2BDirect/ShoppingArea/CatalogSection/CategorySubsection/CachedStoreCatalogDisplay.jsp</name>
  <property name="save-attributes">false</property>
                
  <cache-id>
     <component      id="storeId" type="parameter">
          <required>true</required>
     </component>
     <component      id="catalogId" type="parameter">
          <required>false</required>
     </component>                    
  </cache-id>
</cache-entry>
Nota: Si consume-subfragments está establecido en verdadero (true), cada archivo JSP incluido dinámicamente no necesita su propia <cache-entry>. Tomemos una página web de ejemplo. La siguiente figura muestra una página Item Display personalizada para la tienda B2B avanzada, que contiene información específica de usuario. No es muy útil almacenar en la memoria caché toda esta página entera.

Imagen de ejemplo que muestra una página Visualización de artículo personalizada para la tienda B2B avanzada, que contiene información específica de usuario.

Ejemplo de una página personalizada

La figura siguiente muestra la misma página dividida en fragmentos basados en la posibilidad de reutilización y de almacenamiento en memoria caché. En este ejemplo, la página puede dividirse en distintos fragmentos:

  • Cabecera y lista de solicitudes - lo mismo para todos los clientes.
  • Visualización del producto - lo mismo para todos los clientes para este ID de producto.
  • Barra lateral y Solicitud de presupuesto (RFQ) - igual para todos los clientes con los mismos roles de usuario.
  • Añadir al pedido - igual para todos los clientes con los mismos ID de contrato.

Imagen de ejemplo que muestra la misma página Visualización de artículo personalizada para la tienda B2B avanzada, dividida en fragmentos basándose en la reutilización y el almacenamiento en memoria caché.

Ejemplo de una página personalizada fragmentada para el almacenamiento en memoria caché

En este caso, todos los fragmentos pueden reutilizarse o almacenarse en la memoria caché para una mayor audiencia. Solo es necesario ir a buscar en el sistema de fondo los fragmentos que no se pueden almacenar en la memoria caché, reduciéndose la carga de trabajo en el lado del servidor y mejorando el rendimiento.

Almacenar en memoria caché una página completa excluyendo ciertos fragmentos

En algunos casos resulta práctico impedir que determinados fragmentos se almacenen en memoria caché con una página entera. En lugar de almacenarse en memoria caché con la página completa full page, los fragmentos se almacenan en memoria caché de forma independiente. Por ejemplo, si hay un mensaje de bienvenida personalizado o una minipágina de pedidos actual, se utiliza la propiedad do-not-consume. La entrada padre se marca con la propiedad consume-subfragments y el fragmento hijo que contiene el área de personalización se marcará con esta propiedad do-not-consume. Con esta combinación, el aumento de rendimiento del almacenamiento en memoria caché de páginas completas permanece intacto para la página entera excluyendo el fragmento hijo que se almacena en memoria caché de forma independiente del padre.

La siguiente página web, que es una página de producto común y su barra lateral, incluye dinámicamente un fragmento (MiniCurrentOrderDisplay.jsp) que visualiza una minipágina de pedidos actual personalizada.

Cree normas de ID de memoria caché a fin de almacenar en memoria caché la página de producto y la mini página de pedidos actual. Puesto que la mini página de pedidos actual es exclusiva para cada usuario, para almacenarla en memoria caché, el ID del usuario es el ID de memoria caché. Cree un atributo de solicitud DC_userId para que se utilice el ID de usuario como ID de memoria caché.

A continuación se muestra un archivo cachespec.xml de ejemplo:


<cache-entry>        
        <class>servlet</class>         
       
<name>/AdvancedB2BDirect/ShoppingArea/CurrentOrderSection/MiniCurrentOrderDisplay.jsp</name>
   
        <property name="do-not-consume">true</property>
    
        <property
name="save-attributes">false</property>     
        <cache-id>         
                <component id="DC_userId" type="attribute">  
          
                        
<required>false</required>
                       
<not-value>-1002</not-value>
                </component> 
        </cache-id> 
</cache-entry> 

<cache-entry> 
        <class>servlet</class> 
       
<name>strutsaction</name>

        <property name="store-cookies">false</property>

        <property
name="save-attributes">false</property> 
        <property
name="consume-subfragments">true</property> 
        <cache-id> 
                <component id="" type="pathinfo"> 
                        <required>true</required> 
                       
<value>/StoreCatalogDisplay</value> 
                </component>
                <component id="storeId" type="parameter">
                        <required>true</required>
                </component>
                <component id="catalogId" type="parameter">
                        <required>true</required>
                </component>
        </cache-id>
</cache-entry>

Donde strutsaction está com.ibm.commerce.struts.v2.ECActionServlet.class en HCL Commerce versiones 9.0.0.x, o com.ibm.commerce.struts.v2.ECActionServlet.class en versiones 9.0.1+ y si utiliza la configuración de Strut 2 com.ibm.commerce.struts.v2.ECActionStrutsServlet.class. Cuando se utiliza el atributo de petición DC_userId para crear el ID de memoria caché para la entrada de memoria caché de fragmento en un caso de ejemplo de memoria caché de full page con fragmento, utilice el snippet anterior en el ID de componente. Esto evita que la entrada full page consuma el fragmento incorrectamente debido a que el usuario genérico no ha accedido a la memoria caché en el fragmento almacenable en memoria caché. Si full page consume el fragmento mediante el usuario genérico, los accesos subsiguientes a esta full page por parte de otros usuarios obtendrán incorrectamente un acceso de memoria caché en full page.

La imagen siguiente muestra cómo son las entradas de la memoria caché:

Imagen de ejemplo que muestra cómo son las entradas de la memoria caché para el ejemplo anterior.

A continuación, se muestra el contenido de la entrada de memoria caché MiniCurrentOrderDisplay:

Imagen de ejemplo que muestra el contenido de la entrada de memoria caché MiniCurrentOrderDisplay.

A continuación se muestra el MiniCurrentOrderDisplay que se excluye en la entrada StoreCatalogDisplay de memoria caché:

Imagen de ejemplo que muestra cómo son las entradas de la memoria caché para el ejemplo anterior.

Imagen de ejemplo de la entrada de memoria caché StoreCatalogDisplay, que excluye la entrada MiniCurrentOrderDisplay.

Utilizar DC_userId en una página completa con almacenamiento en memoria caché de fragmentoDC_userId

Cuando se utiliza el atributo de petición DC_userId para crear el ID de memoria caché para la entrada de memoria caché de fragmento en un escenario de memoria caché de página completa con fragmento, utilice el snippet más arriba en el ID de componente.DC_userIdfull page Esto evita que la entrada full page consuma el fragmento incorrectamente derivando en que el usuario genérico no accedida a la memoria caché en el fragmento almacenable en memoria caché. Si full page consume el fragmento mediante el usuario genérico, los accesos subsiguientes a esta full page por parte de otros usuarios obtendrán incorrectamente un acceso de memoria caché en full page. Esto también mejorará el rendimiento del sistema porque permite al usuario genérico obtener accesos de memoria caché en la primera petición, en lugar de hacerlo en el segundo acceso donde el DC_userId se llena con el valor de -1002 del cookie de sesión.


<cache-entry>
<class>servlet</class>
<name>/path_to_JSP/mini-cart.jsp</name>
<property name="do-not-consume">true</property>
<property name="save-attributes">false</property>
<cache-id>
<component id="storeId" type="parameter">
<required>true</required>
</component>
<component id="DC_userId" type="attribute">
<required>false</required>
<not-value>-1002</not-value>
</component>