| Red Hat Docs > Manuals > Red Hat Web Application Framework > |
In order to meet scalability and reliability requirements, web site creators must often use multiple machines to serve the same pages. An installation in which several web servers serve the same pages is a web cluster. Various web cluster configurations provide different features. Common technologies are round-robin DNS and sticky redirectors. Some configurations such as sticky redirectors take steps to send all requests from any one client to the same server in the cluster, but even in such cases, if the server fails, the client request must be handled by a different server.
In the case of Red Hat Web Application Framework, a web cluster involves multiple JVM instances, each running the same Red Hat Web Application Framework code and accessing the same templates and database tables. Each JVM has its own set of object instances and cannot directly access objects in any other JVM. (Traditionally we would say that each JVM has its own address space.) Because subsequent requests from a client may go to different servers, and therefore to different JVMs, Red Hat Web Application Framework cannot associate objects with clients and access those objects across multiple requests without taking the web cluster configuration into account.
There are a few well-known strategies for addressing the problem of associating persistent state with a client, in a web cluster. Of course the developer can store the persistent state in some form of shared storage such as a database; CCM 4.0 and earlier used this strategy for all persistent data. But the developer may want to keep some data in a form that is faster or easier to access; this set of data is called a session. Another approach is to use a sticky redirector or other technique to bind clients to specific servers in the cluster, and simply allow each server to be a single point of failure for its sessions. A third approach is to assign each server in the cluster as a backup for another server, perhaps in pairs or a single ring. Each server sends updates to its sessions to its backup, and if a server fails, requests from that server's clients are handled by the server's backup. Other strategies are possible.
Because this is a well-known problem, the Java2 Enterprise Edition servlet framework provides a generic interface by which servlets can store and access session data. Web containers (also known as application servers or servlet engines) must provide an implementation of this interface. Several web containers (such as BEA WebLogic and Caucho Resin) provide implementations supporting various web cluster strategies. In implementing Red Hat Web Application Framework, we had a choice of whether to simply rely on the web container, or implement our own solution(s).
The advantage of implementing some sort of web cluster support in Red Hat Web Application Framework is that we do not rely on the web container's support, so the web container need not have any support. The Red Hat Web Application Framework user is able to deploy a web cluster using any web container.
The disadvantage of implement web cluster support in Red Hat Web Application Framework is our limited resources. Several web containers are available, supporting a variety of web cluster solutions. If we spend time implementing features that the Red Hat Web Application Framework user can buy elsewhere, we are not spending that time implementing features that only we provide. Also, we cannot implement the variety of solutions available in existing web containers, meaning that some Red Hat Web Application Framework users would prefer to use a web container's implementation anyway.
We have chosen to rely on the web container for web cluster support. This means that a Red Hat Web Application Framework user who wishes to deploy a web cluster must choose a web container that supports his cluster requirements (or modify his requirements to fit his web container).
Example: The Example Corp. wishes to deploy www.example.com on a web cluster. They choose to use a simple round-robin DNS configuration and select Caucho Resin as the web container. They configure Resin to use symmetrical TCP-stored sessions, so each instance of Resin will obtain sessions from other instances in the cluster as necessary.
Example: The Example Corp. wishes to deploy www.example.com on a web cluster. They choose to use a sticky redirector in front of the web servers and select BEA WebLogic as the web container. They configure WebLogic to use in-memory HTTP session replication, so each session will be available on at least two machines in the cluster for reliability.
The J2EE framework provides session support through the HttpServletRequest class and the HttpSession interface. A Java program calls HttpServletRequest.getSession to obtain an instance of HttpSession, and then uses methods on that instance to store and retrieve session data using string keys.
The session data values must be of types that implement java.lang.Serializable (or a few other types which do not apply to Red Hat Web Application Framework). This means that we cannot directly store domain objects unless we make them implement that interface. We may be able to get by simply by storing object keys and important values in HttpSession.
In order to allow the web container to track session IDs for clients that do not support cookies, we must also give the web container the opportunity to modify every URL that we send to the client. This allows the web container to embed the session ID in the URL. The web container implements two methods on the HttpServletResponse class to rewrite URLs: encodeURL and encodeRedirectURL. We should be able to simply call these methods from appropriate places in BeBop to meet this requirement.
All access to the HttpServletRequest and HttpServletResponse objects goes through the Red Hat Web Application Framework kernel's BaseDispatcherServlet class at some point. If we someday decide that Red Hat Web Application Framework should modify or replace the web container's cluster support, we can modify BaseDispatcherServlet to return a wrapper around those objects. The HttpServletRequest wrapper can return our own implementation of HttpSession, and the HttpServletResponse wrapper can implement our own versions of encodeURL and encodeRedirectURL. Any programs that rely on HttpSession or the URL-encoding methods will automatically begin using our cluster implementation.