Web content cache configuration

 

+

Search Tips   |   Advanced Search

 

Contents

  1. WCM caching recommendations
  2. Set the default Web content cache type
  3. WCM Cache
  4. Servlet cache
  5. Forced invalidation of caches
  6. Cache key generation: Servlet caching
  7. Cache key generation: WCM Caching
  8. Automatic invalidation
  9. Automatic invalidation: dependency IDs
  10. WebSphere Edge Server components
  11. Performance Tuning
  12. Recommended Tools
  13. Typical rendering times
  14. Caching scenario
  15. Lean Testing
  16. Graphs: Number of Users in Time
  17. Summary
  18. Recommended Resources
  19. Servlet Caching
  20. Network Dispatcher Configuration
  21. Content Based Router Configuration
  22. Caching proxy configuration
  23. HTTP Server configuration
  24. Skin Timer
  25. Theme Timer
  26. Addenda


WCM caching recommendations

Edge Server caching proxy Recommended for caching resources...

  • images
  • CSS
  • JavaScript

Use instead of WCM basic caching

Servlet caching Recommended for caching of WCM and portlets

Unless it's a very static item, IBM does not recommend using caching proxies to cache HTML. Do not cache items being dynamically cached by the WebSphere Portal Server.

WCM caching When personalization and access control is required.
Static Site Use prerendering and HTTP server. Caching not needed

With servlet caching the goal is majority of requests handled by caching proxy. Should be almost nothing left to do at WCM level. IBM testing has shown a 91% reduction in requests per second on portal server.

 

 

Set the default Web content cache type

To set default Web content caching type, edit...

...and set...

 

Web content cache parameters

Basic cache connect.businesslogic.defaultcacheexpires

    Default expiry for the basic cache. Either a relative period or absolute date and time.

connect.businesslogic.defaultcache

    If true, basic caching is enabled. If false or missing, advanced caching is enabled.

Advanced cache connect.moduleconfig.ajpe.contentcache.defaultcontentcache

    If the advanced cache is enabled, the default advanced cache type is set here.

      SITE | SECURED | PERSONALIZED | USER | SESSION

connect.moduleconfig.ajpe.contentcache.contentcacheexpires

    Default expiry for all advanced caches. It can be either a relative period or an absolute date and time.

Advanced cache: Session connect.sessioncacheconfig.memcachesize

Other parameters...

resourceserver.browserCacheMaxAge Maximum time an item will be stored in a Web browser cache.
resourceserver.maxCacheObjectSize Maximum size of objects that can be cached in kilobytes. By default this is set to 300.

 

Cache expire time formats

For cache expire settings, specify either a relative or absolute time:

{units} =

{date-format-string} =

The last two formats assume GMT.




WCM Cache

WCM Cache settings apply to all content

Basic Low memory usage. Same content for every user. Better to use caching proxy in typical scenario.
Advanced Increased memory usage. Supports access control and personalization. Less configurable than servlet caching for Portal scenario

WCM cache can be manually overriden by GET options for URLs.


WCM basic cache: Configuration

Configuration Options

expirydate applies to all content items

Note that the following disables the WCM Advanced Content cache

Object Cache name:


WCM Basic Cache: URL Override


WCM advanced cache: Configuration

Configuration Options

Object Cache names


WCM advanced cache: Which to use when

For content that is Use Description
Not personalised SITE Every user can access the same cached items
Unique for different groups of users SECURED Users that belong to the same groups will access the same cached items
Unique for different personalization profiles PERSONALIZED Users that share the same personalization profile will access the same cached items
Unique for every user USER Every user gets its own cached items
Unique for every session SESSION Every session gets its own cached items


WCM advanced cache: URL Override

CONTENTCACHE

Will override cache type for referenced URL

CONTENTCACHEEXPIRES

Specifies a new expiry setting




Servlet caching

Servlet caching caches requests at the appserver Web container layer.

Slower than prerendering. Faster than WCM content caching

Servlet caching can cache

Monitoring and management via the Cache Monitor web application.

 

Syndication

If you invalidate cache content before you syndicate, you will invalidate the old content.

If you invalidate during syndication, the old version will be cached again.

Ensure that you invalidate after finishing syndication.

If syndication is set to every 15 minutes, that is effectively the life time of the cache if syndication wipes out all items.

 

Servlet caching: Configuration

Dynamic Cache Service enabled by default. Servlet caching disabled by default.

Cache Monitor used for management. Install from...

Specific cache behaviour defined by...

For example...

By default, some of theme and skin resources will be cached.

Some of the example portlets have predefined cachespec.xml files. For example, for ilwwcm.war...


The results of included JSPs can be cached with servlet cache, depending on consume-subfragments option.

 

Components of the cachespec.xml file

<cache> The root element of the cachespec.xml file, appearing only once. It holds multiple <cache-entry> stanzas.
<cache-entry> There is one of these for each item to be cached. Cache entries can describe items to be cached, items which will invalidate other cache entries, and dependencies between cache entries.
<class> Identifies the type of entry. Possible values are command, servlet, and webservice.
<name> The name of the item to be cached. For commands, it should be the fully qualified package and class name, including the .class suffix. For servlets or JSPs, it should be the URI path relative to the application's context root. For example, if the full URL to the JSP is...

    http://www.myco.com/myapp/products/catalogList.JSP

...the value here would be...

    /products/catalogList.JSP

If you were using the cachespec.xml file from the application server properties directory (global), the entire URL would be necessary. If you have multiple servlet aliases, multiple <name> stanzas could be included here to list each alias that you intend to cache.

<property> Used to set optional properties on a cache entry, such as whether it can be cached outside of WebSphere Application Server, and whether this entry can be persisted to disk. (There is a list of definable properties in the WebSphere Application Server V5 Information Center.) There can be multiple properties per cache entry.
<sharing-policy> Determines whether a cache entry should be shared between distributed caches, and if so, how that should occur. Distributed caches will be discussed later.
<cache-id> Where the cache identifiers for each cache entry are configured. This is a key, similar to a database key structure that identifies a particular cache entry as unique. Caching is generally not as simple as specifying a particular servlet, JSP, or command to cache. These must be qualified with attributes that distinguish one cache entry from another. For example, caching a servlet that returns a weather forecast by the URI...

    /weather/forecast

...would not be desirable; think of what would happen if one user asked for the forecast for Miami and that result was cached, and the following user invoked this URI to get the forecast for Anchorage. In this case, there is probably a request parameter that is sent along with the servlet invocation that has the city name or zip code for the forecast. This is the piece of data that would ensure the cached results are unique and match the request, so, for example, Miami forecasts are always returned to other users asking for Miami weather. This parameter should be designated as required, as the cache entry is meaningless without it. Sample 5, below, shows a similar cache specification. There may also be other parameters as part of the cache ID, such as whether the user is asking for a short-range or long-range forecast. Each component of the cache ID is specified in a <component> tag, as shown in the examples below.


Servlet caching: cachespec.xml

<?xml version="1.0" ?>
<!DOCTYPE cache SYSTEM "cachespec.dtd">

<cache>
  <cache-instance name="jndi/cache-instance-name">
    <cache-entry>

      <class>servlet</class>
      <name>/jsp/html/view-original.jsp</name>

      <sharing-policy>not-shared</sharing-policy>

      <property name="save-attributes">false</property>
      <property name="ignore-get-post">true</property>
      <property name="consume-subfragments">true</property>

      <cache-id>

        <component id="UNIQUE_ID" type="attribute">
          <required>true</required>
        </component>
  
        <component id="WCM_GLOBAL_CONTEXT" type="parameter">
          <required>false</required>
        </component>
  
        <component id="PAGE" type="attribute">
          <required>false</required>
        </component>
  
        <timeout>150</timeout>

        <metadatagenerator>
        com.ibm.pl.fz.randomcacher.RandomCacher
        </metadatagenerator>

      </cache-id>

    </cache-entry>
  </cache-instance>
</cache>

Attributes...


Servlet caching: generic workflow

  1. Create basic version that will cache page
  2. Check that contents of page will change when performing actions
  3. Add components to make actions change content of page
  4. cachespec.xml automatically reloads after changes (typically 5 sec)
  5. Modified JSPs should reload automatically
  6. Repeat

It is tricky!

Advanced caching logic requires populating request attributes before calling WCM servlet

Can be achieved using

Both require Java class creation. Servlet filter requires changing of web.xml. Custom metadata generator need to be put into WEBINF/classes folder

Slower development cycle, requires application restart


Servlet caching: Use with WCM Servlet

Name of WCM servlet is...

Some requests can never be cached, include following in <cache-id> section

<component id="MOD" type="parameter">
    <required>false</required>
    <not-value>Subs</not-value>
    <not-value>Synd</not-value>
    <not-value>ItemDispatcher</not-value>
    <not-value>Syndication</not-value>
    <not-value>MemberFixer</not-value>
    <not-value>VersioningEnablement</not-value>
    <not-value>WorkflowEnablement</not-value>
    <not-value>PlutoUploadFile</not-value>
    <not-value>PlutoDownloadFile</not-value>
    <not-value>AJPECatSelect</not-value>
    <not-value>RefreshAllItems</not-value>
    <not-value>Template</not-value>
</component>

Additional components to include in the cache-id section. All should be marked as not required

id Choose between Draft and Published versions
pagedesign Choose between alternate page designs
version Choose between different versions
source Choose components directly
cmpntname Choose components directly
cmpntid Choose components directly


Servlet caching: Portal Specific

One of the attributes has to be based on portlet ID. You need to differentiate between anonymous and logged in versions. Typically a new view.jsp is created that sets all required attributes and then calls original view.jsp renamed to view-original.jsp

It is not possible to access portlet request from servlet request, which makes custom metadata generators not possible.

WCM rendering portlets have complex rules when to get context path from different URL parameters, session, portlet settings or portlet data. Check original view.jsp. This article includes number of examples at the end. All of those have been proven on multiple customer projects


Servlet caching and Personalization

Caching is not possible without rules how to use ACLs. Use only group names for defining access controls. Create few groups for different kinds of users

Add additional attributes in view.jsp depending on user group. If combinations of groups are allowed create hash from group names (shown later). Add this hash as request attribute

WCM Personalized Caching...

Servlet caching...

Caching scenario: Portal has two portles on front page. User can select local news for one of 20 cities, and industry news for any set of 10 industries.

With WCM personalized caching we would cache up to 20480 copies of combined list. If we split it to two portlets, and use Servlet caching only 1044 copies will be needed.


Forced invalidation of caches

As underlying mechanism for both WCM and Servlet cache is Object Cache, methods are very similar. What is different is creation of caching keys.

Getting cache instance...

Example: Flush a cache

Example: Remove an individual item from the cache


Cache key generation: Servlet caching

All component names are used, semicolon is separator. When component value is null or empty string no value is included

Example:

If "ignore-get-post" is not true:

Additionally CHARSET=UTF8 or other


Cache key generation: WCM Caching


Automatic invalidation

Easy when no syndication is involved. Implement custom workflow stage. Implement servlet that will monitor for content in this stage. When anything found, push to next workflow stage and invalidate url

With syndication, you can add fixed delay, can check & compare. Much harder.


Automatic invalidation: dependency IDs

With portal frequently you need to update set of portlets. You might also need to manually remove content of all portlets in given category. It's hard to find specific content in Cache Monitor for large systems

Solution: Use Dependency IDs which is configured similarly to cache components.

Examples of dependency IDs


WebSphere Edge Server components


Performance Tuning

  1. Basic tuning of JVM
  2. Servlet caching for WCM and portlets
  3. Caching proxy for static resources

Speedup - at least 10 times. Lot of things cached - less work for portal & WCM. Much lower usage of database connections. Less opportunities for memory leaks


Recommended Tools


Typical rendering times


Lean Testing

No need to decide on arbitrary parameters

You get three important numbers

This test runs very fast. Reuse LTPA and sessions. Tune TCP/IP configuration at tester machine. Monitor loading machine CPU usage!


Graphs: Number of Users in Time

Every user runs the same script. New user added every 60 seconds. Two important graphs collected

Remember to monitor loading machine CPU and network. If 80% is reached you need to organize second or faster machine. Fast Ethernet is not THAT fast. Very easy to saturate


Summary


Recommended Resources

 


Servlet caching

WCM content is served up by a View servlet. For example...

To enable the servlet caching at the WebSphere layer, and reduce load at the WCM layer....

  1. Enable servlet caching in the WAS admin console...

      Application servers | WebSphere_Portal | Web container | Enable servlet caching

  2. Create a servlet cache instance. Go to...

      Resources | Cache Instances | Servlet Cache Instances | WebSphere_Portal as the scope | New

  3. Enter portlet-dynacache as the instance name and jndi/portlet-dynacache as the jndi name

  4. To cache content used by the local rendering portlet, deploy the cachespec.xml configuration file to the deployed local rendering portlet's WEB-INF folder...

      wp_profile/installedApps/F32BC/PA_WCMLocalRendering.ear/ilwwcm-localrende.war/WEB-INF

  5. Rename the view.jsp file in...

      wp_profile/installedApps/F32BC/PA_WCMLocalRendering.ear/ilwwcm-localrende.war/jsp/html

    ...to view-original.jsp

  6. Copy the attached view.jsp file in it's place

  7. Restart portal servers.

  8. To verify caching, use the cache monitor application and select the jndi/portlet-dynacache cache instance from the drop down to view the cache's statistics.


Servlet Caching - view.jsp

<%@ page session="true" contentType="text/html" %>
<%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %>
<portletAPI:init/>

<%
 portletRequest.setAttribute("UNIQUE_ID", portletResponse.encodeNamespace(portletRequest.getUser()==null?"":.anonymous"));
 java.lang.StringBuffer sb = new java.lang.StringBuffer();

// Build paging list from all WCM_Page.<MenuID>=<PageNum> parameters java.util.Map params = portletRequest.getParameterMap();
 for(java.util.Iterator i = params.keySet().iterator();i.hasNext();) 
{
    String key = (String) i.next();
    int k = key.indexOf("WCM_Page.");
    if(k>=0) 
    {
        // Store just menu IDs and page numbers
        sb.append(key.substring(k+9));
        sb.append("=");
        sb.append(params.get(key));
        sb.append(";");
    }
}

// If we have any pagers, add them to cache id if(sb.length() > 0)
    portletRequest.setAttribute("PAGE",sb.toString());

%>

<jsp:include page="view-original.jsp"/>


Servlet Caching - cachespec.xml

<?xml version="1.0" ?>

<!DOCTYPE cache SYSTEM "cachespec.dtd">

<cache>
    <cache-instance name="jndi/portlet-dynacache">
        <cache-entry>

            <class>servlet</class>
            <name>/jsp/html/view-original.jsp</name>
            <sharing-policy>shared-push</sharing-policy>

            <property name="save-attributes">false</property>
            <property name="ignore-get-post">true</property>
            <property name="consume-subfragments">true</property>

            <cache-id>

                <component id="UNIQUE_ID" type="attribute">
                    <required>true</required>
                </component>

                <component id="WCM_GLOBAL_CONTEXT" type="parameter">
                    <required>false</required>
                </component>

                <component id="PAGE" type="attribute">
                    <required>false</required>
                </component>

                <timeout>150</timeout>

                <metadatagenerator>
                    com.ibm.pl.fz.randomcacher.RandomCacher
                </metadatagenerator>

            </cache-id>
        </cache-entry>
    </cache-instance>
</cache>


Group Based Personalization - view.jsp

// Create MD5 hash for group based personalization/ACLs
 String grd = (String)portletRequest.getSession().getAttribute("GRD");
 if(grd == null) 
{
    User user = (User)portletRequest.getUser();
    MessageDigest md = MessageDigest.getInstance("MD5");
    List sorted = new LinkedList();

    for(Iterator i = user.getGroups ().iterator(); i.hasNext();) 
    {
        Group group = (Group)i.next();
        sorted.add(group.getName());
    }

    for(Iterator i = sorted.iterator(); i.hasNext();) 
    {
        String name = (String) i.next();
        md.update(name.getBytes());
    }

    byte[] digest = md.digest();
    StringBuffer hex = new StringBuffer();

    for (int i = 0; i < digest.length; i++) 
    {
        hex.append(Integer.toHexString(0xFF & digest[i]));
    }
    portletRequest.getSession().setAttribute("GRD", hex.toString());
}


Multiple Caching Policies

It is worth having multiple WCM portlets on pages:

Need to balance number of views with expiration times. Can be accomplished in two ways:


Multiple Caching Policies - view.jsp

// Get listensTo attribute from WCM config String listensTo = (String)
 portletRequest.getData().getAttribute("WCM_LISTENS_TO");
 if(listensTo==null) 
{
    listensTo = (String)
    portletRequest.getPortletSettings().getAttribute("WCM_LISTENS_TO");
} portletRequest.setAttribute("LISTENS_TO",listensTo);

// Get caching policy from WCM categories String cachePolicy = (String) portletRequest.getData().getAttribute("CATEGORY_OVERRIDE");
 if(cachePolicy==null || cachePolicy.equals(""))
{
    cachePolicy = "DEFAULT";
    portletRequest.setAttribute("CACHE_POLICY",cachePolicy);
}


Multiple Caching Policies - cachespec.xml

<?xml version="1.0" ?>
<!DOCTYPE cache SYSTEM "cachespec.dtd">
<cache>
    <cache-instance name="jndi/portlet-dynacache">
        <cache-entry>
            <class>servlet</class>
            <name>/jsp/html/view-original.jsp</name>
            <sharing-policy>shared-push</sharing-policy>
            <property name="save-attributes">false</property>
            <property name="ignore-get-post">true</property>
            <property name="consume-subfragments">true</property>
            <cache-id>
                <component id="UNIQUE_ID" type="attribute">
                    <required>true</required>
                </component>
                <component id="CACHE_POLICY" type="attribute">
                    <required>true</required>
                <value>DEFAULT</value>
                </component>
                <timeout>150</timeout>
            </cache-id>
            <cache-id>
                <component id="UNIQUE_ID" type="attribute">
                    <required>true</required>
                </component>
                <component id="CACHE_POLICY" type="attribute">
                    <required>true</required>
                    <value>5876533A56C765EA6</value>
                </component>
                <timeout>3000</timeout>
            </cache-id>
        </cache-entry>
    </cache-instance>
</cache>


Metadata Generator: Random Caching Time

 
package com.ibm.pl.fz.randomcacher; import javax.servlet.http.HttpServletResponse; 
import com.ibm.websphere.servlet.cache.CacheConfig;
import com.ibm.websphere.servlet.cache.FragmentInfo; 
import com.ibm.websphere.servlet.cache.MetaDataGenerator; 
import com.ibm.websphere.servlet.cache.ServletCacheRequest;

 public class RandomCacher implements MetaDataGenerator 
{
    public void initialize(CacheConfig cc) {}

    public void setMetaData(ServletCacheRequest scr, HttpServletResponse hsr)
    {
        FragmentInfo fi = scr.getFragmentInfo();
        int timeout = fi.getTimeLimit();
        int rtimeout = timeout+(int)Math.round(timeout*Math.random());
        fi.setTimeLimit(rtimeout);
    }
}


Handle WCM_GLOBAL_CONTEXT - view.jsp

// Get listensTo attribute from WCM config 
String listensTo = (String) portletRequest.getData().getAttribute("WCM_LISTENS_TO");
 if(listensTo==null)
    listensTo = (String) portletRequest.getPortletSettings().getAttribute("WCM_LISTENS_TO");
 String contextPath = null; String portlet = portletRequest.getParameter("WCM_PORTLET");
 if(listensTo.equals("WCM_LINKING_SELF") && portlet != null && portlet.equals(portletResponse.encodeNamespace("WCM"))) 
{
    contextPath = (String) portletRequest.getParameter(portletResponse.encodeNamespace("WCM_CONTEXT"));
}
 if(contextPath==null && !listensTo.equals("WCM_LINKING_NONE"))
{
    contextPath = (String) portletRequest.getParameter("WCM_GLOBAL_CONTEXT");

    if(contextPath!=null)
        portletRequest.getSession().setAttribute("WCM_CONTENT_CONTEXT", contextPath);
}
 if(contextPath==null)
    contextPath = (String) portletRequest.getSession().getAttribute("WCM_CONTENT_CONTEXT");
 if(contextPath==null)
    contextPath = (String) portletRequest.getData().getAttribute("WCM_CONTENT_CONTEXT");
 if(contextPath==null)
    contextPath = (String) portletRequest.getPortletSettings().getAttribute("WCM_CONTENT_CONTEXT");
    portletRequest.setAttribute("WCM_GLOBAL_CONTEXT",contextPath);


Get current page ID - view.jsp

 
String customID = (String) portletRequest.getPortletSettings().getAttribute("CID");
 if(customID==null || customID.equals(""))
    customID = (String) portletRequest.getData().getAttribute("CID");
 if(customID==null || customID.equals(""))
{
    portletRequest.setAttribute("UID", portletResponse.encodeNamespace(""));
    ModelUtil util = com.ibm.wps.model.ModelUtil.from(request);
    NavigationNode node = (NavigationNode)util.getNavigationSelectionModel().getSelectedNode();
    MetaData iMetaData = ((MetaDataProvider)node).getMetaData();
    Object internalPageName = iMetaData.getValue("InternalPage");

    if (internalPageName != null)
    {
        portletRequest.setAttribute("PORTAL_PAGE", internalPageName);
    } 
    else 
    {
        portletRequest.setAttribute("CID", customID);
    }
}


Dependencies and multiple caching policies

<cache-id>
    <component id="UID" type="attribute"><required>true</required></component>
    <component id="ANON" type="attribute"><required>true</required></component>
    <component id="WCM_GLOBAL_CONTEXT" type="attribute"><required>true</required></component>
    <component id="PAGE" type="attribute"><required>false</required></component>
    <timeout>86400</timeout>
    <metadatagenerator>com.ibm.pl.fz.randomcacher.RandomCacher</metadatagenerator>
</cache-id>

<cache-id>
    <component id="CID" type="attribute"><required>true</required></component>
    <component id="ANON" type="attribute"><required>true</required></component>
    <timeout>864000</timeout>
    <metadatagenerator>com.ibm.pl.fz.randomcacher.RandomCacher</metadatagenerator>
</cache-id>

<dependency-id>CID
    <component id="CID" type="attribute"><required>true</required></component>
</dependency-id>

<dependency-id>CTX
    <component id="WCM_GLOBAL_CONTEXT" type="attribute"><required>true</required></component>
</dependency-id>

<dependency-id>PP
    <component id="PORTAL_PAGE" type="attribute"><required>true</required></component>
</dependency-id>


Network Dispatcher Configuration

dscontrol executor start 
dscontrol executor set clientgateway 192.168.1.1 
dscontrol executor set staletimeout 30 
dscontrol executor set fintimeout 30 
dscontrol highavailability heartbeat add lb01 lb02 
dscontrol highavailability backup add primary manual 3333 
dscontrol cluster add www.cluster.com 
dscontrol port add www.cluster.com:80 method mac porttype tcp reset yes 
dscontrol server add www.cluster.com:80:cp01 
dscontrol server add www.cluster.com:80:cp02 
dscontrol server add www.cluster.com:80:http01 
dscontrol server add www.cluster.com:80:http02 
dscontrol rule add www.cluster.com:80:primary type true priority 1 
dscontrol rule add www.cluster.com:80:backup type true priority 2 
dscontrol rule useserver www.cluster.com:80:primary cp01 
dscontrol rule useserver www.cluster.com:80:primary cp02 
dscontrol rule useserver www.cluster.com:80:backup http01 
dscontrol rule useserver www.cluster.com:80:backup http02 
dscontrol executor configure www.cluster.com 
dscontrol manager start 
dscontrol manager smoothing 10 
dscontrol advisor start http www.cluster.com:80 
dscontrol advisor interval http www.cluster.com:80 3


Content Based Router Configuration

 
cbrcontrol executor start 
cbrcontrol cluster add www.cluster.com 
cbrcontrol port add www.cluster.com:80 
cbrcontrol server add www.cluster.com:80:http01 \ advisorrequest "GET /wps/portal HTTP/1.1\r\nHost: www.cluster.com" \ advisorresponse "HTTP/1.1 200 OK" 
cbrcontrol server add www.cluster.com:80:http02 \ advisorrequest "GET /wps/portal HTTP/1.1\r\nHost: www.cluster.com" \ advisorresponse "HTTP/1.1 200 OK" 
cbrcontrol rule add www.cluster.com:80:http1 type true priority 1 
cbrcontrol rule add www.cluster.com:80:http2 type true priority 2 
cbrcontrol rule useserver www.cluster.com:80:http1 http01 
cbrcontrol rule useserver www.cluster.com:80:http2 http02 
cbrcontrol manager start 
cbrcontrol manager smoothing 10 
cbrcontrol advisor start http www.cluster.com:80 
cbrcontrol advisor interval http www.cluster.com:80 3


Caching proxy configuration

On the WebSphere Edge Server, edit ibmproxy.conf, and set...

Proxy /wps/* http://www.cluster.com/wps/* :80
Redirect / http://www.cluster.com/wps/portal :80
CacheMinHold http://* 30 minutes
AggressiveCaching http://*
CacheQueries Always http://* 30 minutes
NoCaching http://*/wps/myportal*
NoCaching http://*/wps/portal*
CacheExpiryCheck off
ServerConnPool on
ProxyPersistence on
CacheMemory 512 M
MaxContentLengthBuffer 500 K
KeepExpired on

Caching Proxy configuration contains lots of comments. You need to locate proper places for above configuration directives.

Remember to remove comments from CBR plugin initialization lines!


HTTP Server Configuration

LoadModule headers_module modules/mod_headers.so
Header set Cache-Control public

This will make all items cacheable.

Set NoCaching directives for dynamic pages.


Skin Timer

Following code added around portletRender tag in Control.jsp of each skin
<div style="border: 1px solid red; padding 2px;">
<% long start = java.lang.System.currentTimeMillis(); %>

<wps:portletRender.> . </wps:portletRender> 

<div style="color: red; padding: 4px; border: solid red; ">


Theme Timer

Following code added in Default.jsp

<body>
<% long pagestart = java.lang.System.currentTimeMillis();%>
.
<div style="color: red; padding: 4px; border: solid red;">
<%= java.lang.System.currentTimeMillis() - pagestart %>ms
</div>
</body>


Addenda

Q: In a multi-server configuration with Dynacache and caching proxies installed, is there a requirement that when a bridge is published? Do we need to invalidate the caches? What should we be doing and what is the approach to doing it?

A: There is no remote API for the caching proxy to invalidate cache items. What you can do is whenever content like images are being changed, make sure you also change the file name.

Q: Does a hardware solution exist that increases [caching] performance?

A: Yes, load balancers and caching proxies on dedicated hardware can help.

Q: Have you seen any caching performance enhancing hardware solutions, or can you recommend any?

A: I have seen several in production, however per policy I can not recommend one specific brand.

Q: Does syndication have any impact on basic or advanced caching?

A: Yes

Q: In our current WCM 5.1 environment with over 15,000 items, a consulting portal architect designed a custom portlet with a custom cache map that boosted performance. Is this a sound approach?

A: It can be. For detailed discussion, listen to audio recording.

Q: Can we use the HTTP servers' caching capability instead of caching proxies?

A: Recommend proxies. HTTP caches mix poorly with WebSphere plug-ins.

Q: We use Personalization heavily in our environment. Is it still better to use the user Advanced Setting rather than none at all?

A: The only drawback of enabling the advanced cache Setting is you might run out of Application Server memory

Q: We use our own Java code in the back end. Would that still work with caching?

A:Yes.

Q: We have an authoring server on WCM version 5.1. Would I need to set up caching on that server as well, or just on servers to which we syndicate?

A: From a usability perspective, it is preferable to not have caching on the authoring server, as it may confuse the authors.

Q: Is servlet caching valid for WCM specific pages, such as if I have two pages in the same site area and I put a JSP in one of those pages drawing dynamic content, for example, cookie information? Is servlet caching valid for caching those types of pages?

A: Yes, you can set the Personalization Cache ID to depend on the cookie value

Q: Do you recommend servlet caching over basic or advanced WCM caching?

A: With cookies, you can do either

Q: As a follow-up to the previous question about syndication wiping out caches, does that happen unilaterally or only to items syndicated?

A: Not sure everything is cleared. Please ask this question via the User Forum, so we can follow up with detailed answers.

Q: Do you have recommended best practices for incorporating edge components?

A: Depends on size of deployment

Q: In one slide you showed a WCM server running Portal. Is that valid?

A: You have to run Portal all the time

Q: With reference to WCM Advanced Caching, how would we invalidate individual cached items in a production server running in a cluster? It was mentioned that there is no way to tell when the syndication process has run, therefore do we have to flush the entire cache? We cannot use the workflow invalidation to programmatically remove these cached items because we author on a separate node in a separate environment which syndicates to a publishing server. If we syndicate every ten minutes, do we have to flush the ENTIRE cache every ten minutes?

A: This advanced caching task is not easy to achieve in such a configuration. You might use the workflow-based solution, but there will be a delay in sending invalidations by the time it usually takes to perform syndication. However, I have seen such solutions working at customer sites. Also remember, that most of cache items will automatically be removed from cache after timeout, or LRU eviction from cache.

Q: In a stand-alone WCM environment (no WebSphere Portal), how do we cache a page for best performance but ensure that the JSP is not cached? We have a JSP (WCM JSP Library Component) embedded within a WCM page, Should we use a tag to NOCACHE the JSP component or some other method?

A: To disable caching for a specific included JSP, you need to create an additional entry in the cachespec.xml file for this JSP and disable caching by adding the property do-not-cache=true. Examples are given in "Mastering DynaCache in WebSphere Commerce" RedBook on page 199.

Q: Instead of using a caching proxy, can we cache on the HTTP server?

A: It is generally possible to configure the WebSphere Plugin to cache content inside the HTTP server using cachespec.xml files. I personally find a caching proxy much easier to configure and to manage than the plugin/esi invalidator combination. The use of proxy and cache modules together with a plugin does not seem to work correctly.

Q: If you have an authoring server, do you need to configure caching there or on the "receiving" server, or on both?

A: It is not recommended to configure caching on an authoring server. It is a best practice to only enable caching on a delivery and receiving server.

Q: Where can we download the page and theme timers?

A: Those timers are small JSP snippets, included in the presentation reference section.

Q: Does syndication wipe the cache only for the syndicated items or for all items?

A: Syndication heavily affects low level WCM caches. By default, after the syndication of each item the caches are cleared. You can delay this cache flushing by using the following options...

...in WCMConfigService.properties. This setting does not affect WCM advanced, basic and servlet caches.

 

Parent topic

Caching options