Edge caching
Caching on the edge is a simple and effective way to improve the performance of your system. The WAS's dynacache has built-in functionality so that setting the EdgeCacheable property of a cache entry to true will allow it to be cached on the edge. This property takes care of the ESI for you, making edge caching easy with virtually no setup overhead.The cache servlet filter creates request attributes with session information to be used by WAS's DynaCache to construct the cache ID, dependency ID, and invalidation ID. Session requests attributes cannot be used to construct the cache ID if the user wants to cache the servlet or JavaServerPage (JSP File) outside of the application server. For Web Server or Edge Server caching, only the URL parameters or cookies can be used as the cache ID. In order to cache WebSphere Commerce store pages the session information is put into session cookies.
Store pages content is based on user session information. In order to cache these store pages the session information is required as part of the Cache ID. By default the session information (language ID, preferred currency ID, parent Organization, contract ID, and member group) is setup as request attributes by the cache filter. In order to cache outside of the application server this information will be stored as session cookies based on the configuration settings in instanceName.xml. These attributes can be renamed, added, or removed in wc-server.xml.
Edge Side Include (ESI) is a simple markup language use to define Web page components for dynamic assembly and delivery of Web applications at the edge of the Internet.
The ESI processor's cache can be monitored through the cache monitor application. In order for the ESI processor's cache to be visible in the cache monitor (refer to Dynamic cache monitor section for more details), the DynaCacheEsi application must be installed as described above and the esiInvalidationMonitor property must be set to true in the plugin-cfg.xml file.
For example,
<?xml version-"1.0"?> <Config> <Property Name="esiEnable" Value="true"/> <Property Name="esiMaxCacheSize" Value="1024" <Property Name="esiInvalidationMonitor" Value="true"/>
Enable edge cookie generation in wc-server.xml
WebSphere Commerce's store pages contents are based on the user session information. Therefore in order to cache these store pages, the session information are needed as part of the cache IDs. Currently the session information (language ID, preferred currency ID, parent Organization, contract IDs and member groups) are setup as request attributes by the cache filter. In WebSphere Commerce 6.0, these session information will be setup as session cookies based on the configuration setting in the wc-server.xml file.
A new feature in WebSphere Commerce 6.0 allows you to enable cookies by changing the enable attribute to true in the following component:
<component compClassName="com.ibm.commerce.dynacache.filter.EdgeCacheCookieHelper" enable=" true" name="DynaCacheCookie"> <property CookieDomain="" CookiePath="/" MutipleStores="true" Timeout="3600" display="false"> <ec name="currencyId" value="true"/> <ec name="parentOrg" value="true"/> <ec name="contractIds" value="true"/> <ec name="memberGroups" value="true"/> <ec name="buyerContractIds" value="true"/> <ec name="userId" value="true"/> <ec name="userType" value="true"/> </property> </component>By changing the value attribute in the above component, you can select which of the following cookies you want to enable or disable:
- WCDC_CURRID (currency id)
- WCDC_PORG (parent organization)
- WCDC_CACHEID1 (contractIds)
- WCDC_CACHEID2 (memberGroups)
- WCDC_CACHEID3 (buyerContractIds)
- WCDC_CACHEID4 (userId)
- WCDC_CACHEID5 (userType)
Enable cookie support
With the capability of caching outside of WAS, it is possible to provide caching for each store. In cachespec.xml the multiple store cache entry includes the store id in the component id. Also, cache-id entries are made for each store. Use Edge Caching in the following way:
- with a single store
- with multiple stores
The DynaCache Event Listener listens to the session change events triggered by the userId or storeId change and then performs the following actions:
- Delete all old session cookies (if they exist)
- Create new session cookies based on the settings of the com.ibm.commerce.dynacache.DynaCacheCookie object and data obtained from the basic catalogue structure
- Each cookie is given an expiry period of one day
- Each cookie is hashed using a one-way hash of the value + merchant key + today's date (yyyymmdd)
- For use of Edge Caching to cache pages outside of the WAS, esiEnable must be set to true. Verify that the esiEnable property is set to true
The ESI processor is configurable through the WebSphere Web server plug-in configuration file, plugin-cfg.xml which is found in the WAS_installdir/config/cells/ directory. For example:
<Property Name="esiEnable" Value="true"/>- Open cachespec.xml in the Web application archive (WAR) WEB-INF or enterprise bean WEB-INF directory.
- Add a property to the cachespec.xml file to enable Edge Caching.
<property name="EdgeCacheable">true</property>- Perform one of the following steps:
- Single store scenario:
- Add the following component entries to the cachespec.xml file inside the <cache-entry> tag
<component id="Component ID" type="cookie"> <required>true</required> </component>
Component ID Definition WC_LANGID Language ID WC_CURRID Currency ID WC_PROG Parent organization WC_CACHEID1 Contract ID WC_CACHEID2 Member groups WC_CACHEID3 Buyer contract ID WC_CACHEID4 User ID WC_CACHEID5 User type
<!-- StoreCatalogDisplay?storeId=10001 --> <cache-id> <component id="" type="pathinfo"> <required>true</required> <value>/StoreCatalogDisplay</value> </component> <component id="storeId" type="parameter"> <required>true</required> <value>10001</value> </component> <component id="catalogId" type="parameter"> <required>true</required> </component> <component id="WC_LANGID_10001" type="cookie"> <required>true</required> </component> <component id="WC_CACHEID5_10001" type="cookie"> <required>true</required> </component> </cache-id> <!-- StoreCatalogDisplay?storeId=10002 --> <cache-id> <component id="" type="pathinfo"> <required>true</required> <value>/StoreCatalogDisplay</value> </component> <component id="storeId" type="parameter"> <required>false</required> <value>10002</value> </component> <component id="catalogId" type="parameter"> <required>true</required> </component> <component id="WC_LANGID_10002" type="cookie"> <required>true</required> </component> <component id="WC_CACHEID5_10002" type="cookie"> <required>true</required> </component> </cache-id>
At runtime the cookie generator dynamically produces a cookie named based on this storeId. For example, given the storeId 10001 and an English store the cookie WC_LANGID_1001=-1 will be generated.
By default, static data such as images and HTML are cached by the ESI processor when served up by the WAS. The cached entries have a default time-out of 300 seconds. The time-out value can be changed by setting the system property com.ibm.servlet.file.esi.timeOut in your JVM.
For example: -D com.ibm.servlet.file.esi.timeOut=60
By default, WebSphere Commerce
does not cache static data. You can enable it by specifying a cache-entry
in the cachespec.xml file. Refer to Simple file servlet section for more details.
To mark an entry to be cached using ESI, use the property EdgeCacheable. This property also implies the property of consume-subfragments. The page will be cached as a full page including all its sub fragments unless one of these sub fragments are specified to be cacheable separately (refer to Caching fragments using ESI for details). To cache pages with ESI, define the Cache ID using parameter and cookie type components. You cannot use request attributes in the cache-id's definition because they are not available at the network's edge.
The following example shows the cache-entry that uses the ESI plugin:
<cache-entry> <class>servlet</class> <name>com.ibm.commerce.struts.ECActionServlet.class</name> <property name="store-cookies">false</property> <property name="save-attributes">false</property> <property name="EdgeCacheable">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>
WebSphere Commerce uses the model-view-controller (MVC) programming model, where calls to a controller servlet might include one or more child JSP files to construct the view. In order for the child JSP files to be edge cacheable, they have to be able to request these JSP files externally. The ESI processor requires that the edgeable fragments be externally requestable on the edge. For example, the fragments should not rely on information set by their parent and other fragments on the same request. Each fragment is routed back through the controller servlet using the alternate_url property set in the cache policy. If the fragments rely on a request attribute set by their parent, these fragment will fail to execute. A possible workaround to this situation is to compute the attribute value using a custom servlet filter that is executed on the alternate_url.
In common product pages, the sidebar dynamically includes a fragment (MiniCartDisplay.jsp) that displays a personalized mini shopping cart.
In order to cache this product page and the mini shopping cart on the edge construct cache ID rules which only contain URL parameters or cookies. For the product page, it will not be a problem since all the information needed to cache it are on the URL. However, since the mini shopping cart is unique per user, in order to cache it on the edge use the user's ID as the cache ID.
Since only URL parameters and cookies can be used to define the cache ID rule, and the URL would not contain the user's information, the only other way is to use a custom cookie that contain the user's ID information and use that as the cache ID. Use servlet filter chaining to chain up with WebSphere Commerce's cache filter to create a custom cookie named WC_USERID based on the request attribute DC_userId as created by the cache filter.
Here is an example of the cachespec.xml:
<cache-entry> <class>servlet</class> <name>/ToolTech/include/MiniShopCart.jsp</name> <property name="EdgeCacheable">true</property> <property name="alternate_url">/servlet/ToolTech/include/MiniShopCart.jsp</property> <property name="save-attributes">false</property> <property name="do-not-consume">false</property> <cache-id> <component id="WC_USERID" type="cookie"> <required>true</required> </component> </cache-id> </cache-entry>
<cache-entry> <class>servlet</class> <name>com.ibm.commerce.struts.ECActionServlet.class</name> <property name="store-cookies">false</property> <property name="save-attributes">false</property> <property name="EdgeCacheable">true</property> <cache-id> <component id="" type="pathinfo"> <required>true</required> <value>/TopCategoriesDisplay</value> </component> <component id="storeId" type="parameter"> <required>true</required> </component> <component id="catalogId" type="parameter"> <required>true</required> </component> </cache-id> </cache-entry>