Load-Balancing Options


When you're using a servlet engine and Web server in a production environment, one of the most important factors is response time. Of course, your site won't respond if the server fails or it's been swamped with requests. One solution to this problem is to provide a higher level of reliability and load balancing through additional server machines and duplicate copies of the server software. Resin supports the ability to load-balance requests in just this fashion. In this chapter, we explore several options for providing load balancing within Resin. In addition, we explain how sessions are handled across a server farm.

Sessions

As you know, sessions are designed to hold information about a current user on the site. Probably the best example is a shopping cart on a commerce site. The session keeps track of the cart as well as the user doing the shopping. As each request comes from the user, the right cart needs to be modified.

When all your user requests come to a single Web server and servlet engine, you can keep the Session objects in memory; that way, they can be easily accessed when the user makes a new request. But what happens when a request from the user is sent to different servers? The servers in the farm cannot assume they know anything about the current users because they might be seeing every fourth or even more random requests from the same user. Resin provides three possible solutions: srun indexing, distributed sessions, and TCP-ring distributed sessions.

srun Indexing

Since you know that each request from a user will go to any of the servers in a server farm, one way to handle sessions is to ensure that requests from a user are sent to a specific server based on that user's initial request. With this scheme, a user whose request is handled by server a will always have their requests sent to server a. Server a will have the Session object for the user in memory and be able to handle all of the specific information for the user.

In Resin 3.x, the configuration has changed. The <cluster> element has been introduced to produce a configuration like:

 <server>     <cluster>       <srun server-id='servera' host='192.168.1.101' port='6802' index='1'/>       <srun server-id='serverb' host='192.168.1.102' port='6802' index='2'/>       <srun server-id='serverc' host='192.168.1.103' port='6802' index='3'/>     <cluster> 

Figure 19.1 shows an example using this configuration.

click to expand
Figure 19.1: srun indexing configuration.

In this configuration, we assume there are three Resin engines running on three different servers. Requests can be made of any of the servers. When a client makes a request, a cookie is saved on the client's machine with the cookie containing a certain prefix. That prefix is used in subsequent requests to indicate which of the three servers should get the new request. If the user is supposed to be handled by serverb but that server fails, the request goes to serverc and the user's session is lost.

Distributed Sessions

One problem with the solution we just described is a lack of reliability provided by the server saving the session in memory. If the box were to fail or even if a Java Virtual Machine (JVM) were to fail, the sessions associated with it would be lost. You need to a way to save the session so that all of the servers can access it regardless of which one receives a request from the user. There are two solutions to this problem: symmetrical sessions and sticky sessions.

Symmetrical Sessions

With symmetrical sessions, most of the session management is assigned to the JVMs. When a client browser makes a request, the receiving JVM pulls the session information from a storage location to update and save it as needed. No management is needed on the load-balancer side of things because the servlet engines don't care whether they have seen a previous request from the current client—they just pull a previously saved session. Figure 19.2 shows an example of how this type of system works.

click to expand
Figure 19.2: Symmetrical session handling.

When a client makes a request, the server stores a cookie on the client and also stores the session in a storage mechanism, such as a database. When another request is made from the same client, the server pulls the cookie and uses the information within it to pull the session from storage. In this scenario, you don't care about any of the previous requests and which server handled it. When building a configuration file for symmetrical session handling, make sure that the <always-load-session> attribute appears in the <session-config> element. This attribute tells the server to load the session of the requesting client for all requests.

The Resin server saves the session data to storage only when an attribute of the session is changed. If have an object as a session variable and you change an internal attribute of the object, the server won't recognize that the session has changed. In this case, you can force a save with the <always-save-session> element. You can also use the <save-on-shutdown/> element to save sessions only when the Resin server shuts down.

Sticky Sessions

Sticky sessions are a combination of the srun indexing and distributed sessions. All requests from a client are sent to a specific server based on a client's initial contact with the server group. At the same time, the session is stored so any server in the farm can obtain it in case that server fails.

Database-Distributed Sessions

Once a server has a session and needs to save it, a storage mechanism must be in place. One of the most popular options is to use a database. While storing the session in a database is relatively easy, there can be a performance issue on a poorly maintained database. To handle any performance issues, you can use a separate server and database solely to handle session stores and retrievals. This is known as database-distributed sessions.

To use this approach, you must create a <resource-ref> element in the Resin configuration file for the database server handling session requests. Once you do, the Resin server automatically creates a table in the server and database specified by <resource-ref>. The table will have the following schema:

 CREATE TABLE session (   id VARCHAR(64) NOT NULL,   data BLOB,   mod_time TIMESTAMP,   PRIMARY KEY(id) ) 

The Resin configuration file should look something like the following:

 <web-app>   <session-config>     <jdbc-store>jdbcStore</jdbc-store>     <always-save-session/>   </session-config> </web-app> 

TCP-Ring Distributed Sessions

As you might guess, the session database server becomes a single point of failure as well as a performance bottleneck. You can still take advantage of load balancing and maintaining secure and reliable sessions through TCP-ring distributed sessions. In this protocol, the servers are logically arranged in a ring. Sessions are distributed throughout the ring, thus providing all servers with copies of all sessions in memory. There is no single point of failure in the system. The configuration is:

 <resin xmlns="http://caucho.com/ns/resin"> <javac compiler='jikes'/> <server>   <cluster>     <port server- port='6810' index='1'/>     <port server- port='6811' index='2'/>     <cluster-store jndi-name="caucho/store" path="file:/tmp/caucho/qa/session"/>   </cluster>   <host id=' '>     <web-app id='/'>       <session-config persistent-store="caucho/store"/>     </web-app>   </host> </server> </resin> 

File-Distributed Sessions

During application development where servers are reset and applications loaded and restarted, sessions can be lost very easily. To keep the session information available but avoid using a database for storage or multiple servers, you can use a file store. For example:

 <web-app>   <session-config>     <file-store>WEB-INF/sessions</file-store>   </session-config> </web-app> 

This configuration tells Resin to use a directory called sessions to hold all sessions created during the execution of the server. As a session is updated, the new session data is written to the file store. When an application is reloaded or the server is restarted, Resin reads all session information found in the store. You should not use a file store-based solution in a multiserver environment because Resin was not designed for this type of configuration.




Mastering Resin
Mastering Resin
ISBN: 0471431036
EAN: 2147483647
Year: 2002
Pages: 180

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net