Most Read This Week
Edge Computing with Java Edge Side Includes
An end-to-end architectural illustration
Jul. 2, 2004 12:00 AM
Content Delivery Networks (CDNs) have been used commercially to cache static content across a distributed network. Edge Side Includes is a W3C-acknowledged submission that supports the fragment assembly model. It provides the semantics on how to assemble dynamic content at the edge, when to cache content, when to expire content, etc. Java Edge Side Includes (JESI) provides extensions to Java that make it easy to program JSPs through a custom JSP tag library that will generate ESI markup. In this article we'll describe how to develop applications using JESI and show its impact on the end-to-end architecture.
A typical Web application may be browsed more often for its nontransactional static content than for its business transactions that require a trip to its back-end systems. In such a scenario it's cost-effective to serve some of the content on multiple low-cost edge servers and preserve the back-end compute and network resources for business operations that have transactional requirements.
Standard caching mechanisms, be it on the edge or near the enterprise, are designed to operate with minimal dependency on the back-end enterprise application. The caching entity caches a whole HTTP object and refreshes it based on its cache life properties specified through HTTP headers. This works well for "static" content that can be treated as indivisible objects. There is no mechanism, excluding a few proprietary ones, for applying caching to dynamic content. Edge Side Includes (ESI) was born out of the need for filling this void.
Edge Side Includes is a simple markup language that developers can use to identify content fragments for dynamic assembly at the network edge. ESI defines three main elements:
Figure 1 shows a comparison of ESI before and after. Without ESI, client browsers from the Internet issue requests to access content from a particular site hosted in a data center. These requests funnel into the many Web and application servers. Every request that comes from client browsers gets serviced by both the Web and application servers and eventually database servers. With ESI, it's possible to offload the burden from the Web server and application server to "Edge Servers" deployed close to the consumers. The requests from client browsers get serviced by these edge servers, which serve cached content a lot faster. Every now and then, when the cached content expires, it results in a trip to the origin server to update the ESI fragment. With such architecture, the burden on the "Content Generation" infrastructure is drastically reduced.
Java Edge Side Includes
Though JESI resembles "JSP include", the two have entirely different operational characteristics. A JESI include generates an ESI positional marker for ESI processors to construct the page. Construction of a page will involve hits to only those JESI include pages that have expired or are not in cache. Further, each JESI include page is fetched by a separate HTTP request. Hence, a JSP page should not assume that the HTTP request object passed to an include page will be the same as that passed to the containing JSP page. This should be bourne, especially when migrating an old Web page to JESI technology.
Before describing JESI tags, we must delineate two models of usage of JESI tags. There's a template/fragment model and a control/include model. It's important that JESI be flexible enough to be easily used with old Web pages and at the same time provide richer control for new Web page development. It's difficult to convert old Web pages into component Web pages to be "included" into the main composite Web page. The template/fragment model is used to convert old applications to JESI with relatively little effort. In this model a page is broken up into cacheable fragments, each fragment with its own cache properties, and the page outside of the fragments is marked up with the "template" tag. The "control/include" model is recommended for creating new Web pages. The Web page's cache control properties are provided under the "control" tag and other pages are included with the "include" tag. As with fragments, an included page has its own cache properties.
Listing 1 illustrates the syntax of some of the JESI tags. The JESI specification in the reference section provides comprehensive coverage of all the tags. <jesi:control> sets the caching characteristics of a page composed of "include" pages. It should be placed to surround the cacheable content of the page. The properties of the tag affect the content within the control tag but outside of the "include" tags. The properties of the tag in a page do not apply to the included pages. <jesi:include> is used to include cacheable resources identified by a URL. The JESI include tag, which is similar to a JSP include tag, is different in that JESI include tags are fetched by the ESI processor with separate HTTP requests.
The consequences of this provide a key to when it is appropriate to replace a JSP include with a JESI include. The include tag can be used in a template/fragment model as well. <jesi:template> tag, like the control tag, affects the HTTP headers only and does not generate HTML tags. The template tag is intended to be used with JESI fragments and controls cache characteristics of content in the page outside of fragments but within the template tag. In other words, the content outside the fragments but within the template tag is one cacheable object.
The main intent of the template tag is for the conversion of existing pages to the JESI model. In this model, the ESI processor's defaults will not apply to the page in the absence of a template tag. <jesi:fragment> tag is a cacheable object to be used in the template/fragment model to divide pages into individual cacheable components. Fragments have the same cache properties as template or control tags. Just like the template tag, a fragment has its own cache control and cannot inherit properties from the template or from the ESI processors. <jesi:codeblock> tag is used to conditionally execute code outside of fragments in the template/fragment model. The conditions specify if the code is to be executed when a template or a fragment is fetched by the ESI processor. <jesi:invalidate> allows the JSP programmer to invalidate cache objects. If a prefix is specified, the directive applies to all objects with the specified prefix. The username/ password attributes provide an authentication mechanism for logging into the cache server to execute the directive. Invalidate uses ESI's invalidation protocol, which is executed over HTTP. The optional "cookie" and "header" information can be used to determine what to invalidate. The <jesi:personalization> tag allows the ESI processor to set cookie values in responses, thus saving a trip to the origin Web server. If the cookie was found in the request header and has a non-null value, that value is used. If the cookie is not found in the header or the value is null, the value specified in the tag is used.
The source JSP processor processes the refresh requests from the ESI processor as follows (see Figure 3).
Request for a Template
Request for a Fragment
Request for an Include Page
Also assume that a blood donation campaign is in progress and that the organizers want to display a bar chart showing their goal regarding the number of donors and the number of people signed up so far as part of all corporate pages. This information is stored in a special database table and is updated four times a day. The chart is a good candidate to be an additional JESI fragment. Therefore, you would add a JESI template tag at the top of the page and use JESI fragment tags to enclose the fragments that are to be cached as separate entities.
Assume that the URL to the corporate page is www.acme.com/employee_page.jsp. Figure 4 shows the JSP code snippet and the ESI-embedded response beginning with the header.
The ESI processor is alerted by the Surrogate-Control response header. Note the no-store directive, generated because of the cache="no" setting in the JESI template tag. The ESI processor makes two additional requests, where it fetches and caches the two fragments. After that, the composite page is returned to the employee. When the employee works with the page again, the dynamic content will be newly generated but the chart and the footer will be served from the cache.
Without JESI and ESI, you can at best cache static content on a surrogate (reverse proxy) and force the enterprise server to generate the dynamic content for each request without consideration of the dynamicity of the various parts. The only alternative would be to let the application be aware of the cache life of the various parts and cache internally, though this is hardly a recommended or practiced option as it makes both development and maintenance complex and error prone.
Using JESI and ESI, however, the page could naturally be broken down into component parts based on the life of each part and let the ESI processor orchestrate composition of the page to be served up.
In summary, JESI will be effective when effort is spent on optimally designing Web pages with careful consideration to the cache-life of the components. This will require careful thought as to content regeneration policies.
Reader Feedback: Page 1 of 1
Subscribe to the World's Most Powerful Newsletters
Today's Top Reads