Monday, October 7, 2013

dynamic cache in WebSphere

Dynamic Cache supports caching of Java servlets, JavaServer Pages (JSP), WebSphere command objects, Web services objects, and Java objects.
*  The concept of caching static information in a browser, proxy or a webserver provides an effective way to reduce network and processing requirements. A larger overhead of many web applications is related to the serving, not of static content, but of dynamic content based on user input and retrieval of data from backend resources such as databases.
How to enable Dynamic Cache
*  Dynamic cache is enabled by default on V6.1 WebSphere AppServers.
*  To enable Servlet and JSP caching from the admin console, navigate to the web container
Servers –> Application Servers -> <select server> -> webcontainer settings –> webcontainer
*  Check ‘Enable servlet caching’
*  Save and restart the Application Server to put the changes into effect.

Specify what to be catched
- Now servlet caching is enabled, if is necessary to define which dynamic content will be cached and the rules by which it will be cached or invalidated. servlet and JSP caching will be policy based using the cachespec.xml file. The preferred location for the cachespec.xml file is within the web applications WEB-INF folder.
<cache>
<cache-instance name=”offloadtest”>
<cache-entry>
<class>servlet</class>
<name>/test.jsp</name>
<property name=”consume-subfragments”>true
<exclude>/Time.jsp</exclude>
</property>
<cache-id>
<component id=”name” type=”parameter”>
<required>true</required></component>
<timeout>180</timeout>
<inactivity>60</inactivity>
</cache-id>
</cache-entry>
</cache-instance>
</cache>
While the timeout directive dictates how long content can remain in cache before being refreshed, the Inactivity directive can cause a refresh prior to the timeout when a page is not used frequently.
The consume-subfragments property tells the cache not to stop saving content when it includes a child servlet. The parent entry will include all the content from all fragments in its cache entry, resulting in one big cache entry.
Use the <exclude> element to tell the cache to stop consuming for the excluded fragment and instead, create a placeholder for the include or forward.
A dependencyID identifies a cache entries dependency based on certain factors, such that when those factors occur they trigger an invalidation of all the cache entries that share this dependency.
How it works?
- The first request will result in a cache MISS. Full processing takes place for Time.jsp. The response is returned to the browser but also loaded into cache.
- Subsequent requests for Time.jsp result in a cache HIT until the cached copy of Time.jsp is invalidated.
Monitoring Dynamic cache
*  Once Dynamic caching is configured, and dynamic content is cached, the content of the cache can be examined and monitored using the cachemonitor.
*  An enterprise application called CacheMonitor is provided with WebSphere Application server. It is available in the folder <WebSphere InstallRoot>/installableApps and called CacheMonitor.ear.
Disk Offload
*  By default, when the number of cache entries reaches the configured limit for a given application server, cache entries are removed from the memory cache, allowing newer entries to be stored in the cache. Use disk offload to copy the cache  entries that are being removed from the memory cache to disk for potential future access. Disk offload is configured via the adminconsole either globally or for a specific cache instance.
Cache Instances
*  Since different webapplications or pages may have different caching requirements, unique cache instances can be created for each. This allows applications to have greater flexibility and better tuning of cache resources.
*  The characteristics of each servlet cache instance are a unique jndi name, disk offload policies, cache configuration and performance parameters.
Configure a new cache instance
goto Resources –> Cache Instances –> Servlet Cache Instance –> new
*  A jndi name must be given to the cache instance which will be used to refer back to the instance in cachespec.xml.
*  Check ‘Enable disk offload’ and specify a disk off load location, cache size and cache entry limits.
Cache Invalidation
*  It is essential that timely invalidations of cached content take place for the integrity of the website.
Mechanisms for invalidation are:
-timeout or inactivity directives within cachespec.xml
-group-based invalidation mechanism through dependency IDs.
-Programmatic invalidation via the cache API ‘com.ibm.websphere.cache.*’
-The CacheMonitor
Some Tips
*  WebSphere Application Server uses JVM memory to store cached objects. Therefore, it is important to know how much memory can be allocated for the cache and based on this information you can set the cache size to the proper value.
*  Increase the priority of cache entries that are expensive to regenerate.
*  Modify timeout of entries so that they stay in memory as long as they are valid.
*  If the estimated total size of all cached objects is bigger than the available memory, you can enable the disk offload option.
*  Increase the cache size if memory allows.

Friday, October 4, 2013

Understanding virtual host mapping in WebSphere Application Server

Together with the context root, the virtual host assigned to a Web module determines under which URLs that Web module will be accessible. In WebSphere, a virtual host is simply a set of host aliases, where each alias specifies a host name (or a * wildcard to match any host name) and a port number. Configuring virtual hosts is pretty straightforward, but problems may occur if there are multiple virtual host definitions that have overlapping host aliases, i.e. if the same host name/port combination is matched by multiple virtual hosts.
To see why this happens, it is important to understand how virtual host mapping in WebSphere works internally. Each application server maintains a map with the following structure:
{ host alias → { context root → Web module } }
That means that for each host alias, there is a separate map that maps from the context root to the Web module. Entries in these data structures are created (resp. removed) as Web modules are started (resp. stopped). Note that at this point wildcards are not replaced yet.
To illustrate how this works, consider the following sample topology:
  • A WebSphere application cluster with two members running on hosts srv-a.example.org and srv-b.example.org and listening on port 9080.
  • A Web server having two host names web1.example.org and web2.example.org and listening on port 80.
  • Two Web modules module1 (with context root /app1) and module2 (with context root /app2) that are expected to answer requests on host names web1.example.org and web2.example.org respectively.
If one further assumes that module1 and module2 should also accept requests sent directly to srv-a.example.org and srv-b.example.org (i.e. without going through the Web server), then one would define the following virtual hosts:
  • vhost1 with aliases web1.example.org:80 and *:9080.
  • vhost2 with aliases web2.example.org:80 and *:9080.
module1 would be mapped to vhost1 and module2 would be mapped to vhost2. Both cluster members would then build the following map internally:
AliasContext rootWeb module
web1.example.org:80/app1module1
web2.example.org:80/app2module2
*:9080/app1module1
/app2module2
The structure of the map described above implies that mapping a request to a Web module is a two-step process. WebSphere will first match the Hostheader of the incoming request. At this point, wildcards are processed. WebSphere will then use the corresponding { context root → Web module } map to look up the Web module based on the path part of the URL.
In the example shown above, the fact that the same host alias appears in multiple virtual host definition doesn't cause any issue. Any request sent directly to the application servers via port 9080 will be routed correctly to the expected Web module.
Now consider a slightly different virtual host configuration:
  • vhost1 with aliases web1.example.org:80 and *:9080.
  • vhost2 with aliases web2.example.org:80srv-a.example.org:9080 and srv-b.example.org:9080.
This will result in the following map:
AliasContext rootWeb module
web1.example.org:80/app1module1
web2.example.org:80/app2module2
*:9080/app1module1
srv-a.example.org:9080/app2module2
srv-b.example.org:9080/app2module2
In this case, things will not work as expected. In fact, requests for http://srv-a.example.org:9080/app1/index.html will not be routed tomodule1. As noted earlier, WebSphere will first match the Host header against the host aliases. The value of that header (srv-a.example.org:9080) matches both *:9080 and srv-a.example.org:9080, but WebSphere will select the second one because it is more specific than the alias with the wildcard. WebSphere will then look at the { context root → Web module } map for that alias. The problem is that this map now contains a single entry mapping /app2 to module2, i.e. there is no entry matching /app1/index.html.
The conclusion is that when configuring virtual hosts, a problem will occur if one virtual host has an alias of the form host:port and another one has an alias *:port with the same port number.