Oracle9i Application Server Best Practices Release 2 (9.0.3) Part Number B10578-02 |
|
This appendix contains lengthier discussions of Oracle9iAS Web Cache best practices in the main sections of this document. It features the following topic:
Personalization is common in dynamic content. There are at least three common challenges when caching personalized content:
To solve the first two challenges, Oracle9iAS Web Cache operates in a partial-page model, in which each Web page can be divided into a template and multiple fragments that can in turn be further divided into templates and lower level fragments. Each fragment or template is stored and managed independently; a full page is assembled from the underlying fragments upon request. Fragments can be shared among different templates, so that common fragments are not duplicated to waste precious cache space. Sharing can also greatly reduce the number of updates required when fragments expire. Depending on the application, updating a fragment can be cheaper than updating a full page. In addition, each template or fragment may have its own unique caching policies such as expiration, validation, and invalidation, so that each fragment in a full Web page can be cached as long as possible, even when some fragments are not cached or are cached for a much shorter period of time.
Oracle9iAS Web Cache uses ESI, to achieve flexible partial-page caching. ESI is a simple markup language for partial-page caching. Applications can mark up HTTP responses with two different kinds of tags, inline and include, that define the fragment/template structure in the response.
To address the third challenge in caching personalized content, Oracle9iAS Web Cache allows application developers to use variables in an ESI template. Because variables can be resolved to different pieces of request information or response information, the uniqueness of templates and fragments can be significantly reduced when personal information abounds.
There are two kinds of ESI variables: request variables and response variables. When an ESI template is assembled, a request variable is instantiated to a piece of request information such as a query string parameter, a cookie, or an HTTP header. For example, when a request for a dynamic page carries an application session ID in a query string parameter, this page may contain many hyperlinks with ESI request variables accessing this session ID, so that generated hyperlinks can carry the session ID into the next clicked page.
A response variable is similar to a request variable, except that its value comes not from the request, but from a special fragment called ESI environment. An ESI environment is essentially a special type of fragment whose response defines a set of variables that can be accessed by response variable occurrences in the enclosing template. For example, a dynamic page with a calendar may need to present personal appointments that cannot be stored in browser cookies due to cookie size limits. The application can instead reference a "profile" environment fragment in the template, and refer to all appointments in the environment without making separate requests for each appointment. In addition, an environment may be used to merge multiple small fragments into one environment by which each fragment can be referenced through response variable instantiation. This reduces storage and retrieval overhead similarly.
To encourage rapid adoption of ESI by Java developers, the creators of ESI have also published the Edge Side Includes for Java (JESI) specification. JESI is actively making its way through the Java Community Process standards body as JSR 128. As a specification and custom JSP tag library that developers can use to automatically generate ESI code, JESI facilitates the programming of Java Server Pages (JSPs) using ESI. While developers can always use ESI tags directly within their JSP code, JESI represents an easy way to express the modularity of JSPs and the caching of those modules, without requiring developers to learn a new programming syntax. JESI generates the appropriate ESI tags and headers in the JSP output that instruct ESI processors, such as Oracle9iAS Web Cache, to cache (or not) templates and fragments for the appropriate duration. JESI also facilitates the partial execution of JSPs when an ESI processor requests fragments and templates. Both OracleJSP (part of Oracle9iAS Containers for J2EE) and Oracle JDeveloper9i support the use of ESI and JESI, and both currently ship with the JESI tag library.
See Also:
|
The <esi:inline>
and <esi:include>
tags enable applications to adopt ESI page fragmentation and assembly.
Review the following sections:
Most existing applications are only designed to output an entire Web page to HTTP requests. These fragments and templates are non-fetchable, meaning they are not to be fetched independently from the origin server. If a cache needs any of these fragments or templates, the corresponding full Web page must be requested. To use ESI page assembly for non-fetchable fragments, an application can output the full-page response just as it does normally, with the exception that at the beginning and the end of each fragment, an <esi:inline>
tag is inserted with a fragment name to demarcate the fragment. Oracle9iAS Web Cache stores the enclosed portions as separate fragments and the original page as page templates without the enclosed fragments. Fragments are shared if their names are identical.
When an application uses non-fetchable <esi:inline>
fragments, the full page must be requested for every cache miss. At first, it can appear that there is no apparent cache benefit for cache misses. However, non-fetchable <esi:inline>
fragments improves overall caching by:
<esi:inline>
fragmentation, only one cache update of any full page containing this fragment is enough to bring all full pages sharing this fragment current. Therefore, even non-fetchable <esi:inline>
fragments can significantly reduce cache update frequency. The cost reduction is proportional to the degree of sharing.
<esi:inline>
is primarily intended for pages with cacheable fragments. If a page contains non-cacheable, non-fetchable fragments, then the use of <esi:inline>
is not recommended. However, the update of this full page may still offer benefit if it contains some cacheable fragments that are shared with other pages.
The <esi:include>
tag is another way to define fragments and templates in an HTTP output for dynamic content caching and assembly. It is in many ways similar to the <esi:inline> tag. It defines a name for the defined fragment.
The page including an <esi:include>
tag is a template that references the defined fragment. However, it also has some key differences which makes its applicable scenarios very different from those of <esi:inline>:
<esi:include>
tag in a template only defines the reference to a fragment.
It does not enclose an embedded fragment directly in the template.
<esi:include>
tag must always be independently fetchable by HTTP or HTTPS.
The requested URL is the same as the fragment name. In contrast, an <esi:inline> tag's name only identifies the uniqueness of the fragment and is not used to fetch the actual content. The attribute defining the fragment name in <esi:include>
fragment is src instead of name.
There are at least two scenarios where using <esi:include>
tags is beneficial:
<esi:include>
tags fetch and assemble directly, reducing one layer of redundancy.
<esi:include>
is used for page fragmentation and assembly, Oracle9iAS Web Cache can miss only on the templates or fragments when most or all fragments are already cached, saving effective cache miss cost. In many cases, it is also valuable to cache the personalized templates because these seldom change.
When Oracle9iAS Web Cache receives an advanced invalidation request, it traverses the contents of the cache to locate the objects to invalid. Depending on the structure and number of objects cached, it can take time for Oracle9iAS Web Cache to invalid content. Here are some ways you can expedite cache content traversal:
Also review the following sections:
When you need to invalidate one object in the cache, send a basic rather than an advanced invalidation request to avoid cache traversal.
To send a basic invalidation request, use the Basic Invalidation option in the Content Invalidation page (Administration > Content Invalidation) in Oracle9iAS Web Cache Manager or specify the BASICSELECTOR
element in a manual invalidation request.
For example, the following request invalidates a document exactly matching /contacts/contacts.html using the BASICSELECTOR
element:
<?xml version="1.0"?> <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd"> <INVALIDATION VERSION="WCS-1.1"> <OBJECT> <BASICSELECTOR URI="http://www.company.com:80/contacts/contacts.html"/> <ACTION REMOVALTTL="0"/> </OBJECT> </INVALIDATION>
Advanced invalidation requests should be reserved for invalidation of multiple objects.
To send an advanced invalidation request, use the Advanced Invalidation option in the Content Invalidation page or specify the ADVANCEDSELECTOR
element in a manual invalidation request.
When multiple objects share a common URL, request POST
body, or an embedded URL
parameter, you can express the common elements in multiple ways:
For the quickest invalidation, Oracle Corporation recommends using the OTHER
element to specify a substring for literal matching rather than regular expression for pattern matching.
To send an advanced invalidation request with substring matching:
OTHER
element in a manual invalidation request that uses the ADVANCEDSELECTOR
element.
NAME
attribute to use a value of URI
, BODY
, or QUERYSTRING_PARAMETER
.
TYPE
attribute to use a value of SUBSTRING
.
For example, the following request searches for any documents underneath http://wc-cluster.us.oracle.com:1100/pls/portal/!PORTAL.wwpro_app_provider.execute_portlet/595897563/
, that match the following criteria:
POST
request method
Portlet.Show
POST
body contains _language=EN-US
x-oracle-cache-user
and x-oracle-cache-subid
_portlet_id
and _provider_id
<?xml version="1.0"?> <!DOCTYPE INVALIDATION SYSTEM "http://www.oracle.com/webcache/90200/WCSinvalidation.dtd"> <INVALIDATION VERSION="WCS-1.1"> <OBJECT> <ADVANCEDSELECTOR URIPREFIX="/pls/portal/!PORTAL.wwpro_app_provider.execute_portl et/595897563/" HOST="wc-cluster.us.oracle.com:1100" METHOD="POST"> <OTHER NAME="QUERYSTRING_PARAMETER" TYPE="SUBSTRING" VALUE="_portlet_id=2"/> <OTHER NAME="QUERYSTRING_PARAMETER" TYPE="SUBSTRING" VALUE="_provider_id=595897563"/> <HEADER NAME="x-oracle-cache-user" VALUE="PORTAL"/> <HEADER NAME="x-oracle-cache-subid" VALUE="1"/> <OTHER NAME="BODY" TYPE="SUBSTRING" VALUE="_language=EN-US"/> <OTHER NAME="URI" TYPE="SUBSTRING" VALUE="showPortlet.Show"/> </ADVANCEDSELECTOR> <ACTION REMOVALTTL="0"/> <INFO VALUE="Invalidate an old portlet based on portlet ID and provider ID"/> </OBJECT> </INVALIDATION>
|
Copyright © 2003 Oracle Corporation. All Rights Reserved. |
|