Difference between revisions of "Jetty/Feature/Session Clustering Using a Database"

From Eclipsepedia

< Jetty‎ | Feature
Jump to: navigation, search
m (New page: =Session Clustering using a Database= Jetty can support session clustering by persisting sessions to a shared database. Each Jetty instance locally caches sessions for which it has receiv...)
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
=Session Clustering using a Database=
 
=Session Clustering using a Database=
 +
 +
{{Jetty Redirect|http://www.eclipse.org/jetty/documentation/current/session-clustering-jdbc.html}}
  
 
Jetty can support session clustering by persisting sessions to a shared database. Each Jetty instance locally caches sessions for which it has received requests, writing any changes to the session through to the database as the request exits the server. Sessions must obey the Serialization contract, and servlets must call the Session.setAttribute() method to ensure that changes are persisted.
 
Jetty can support session clustering by persisting sessions to a shared database. Each Jetty instance locally caches sessions for which it has received requests, writing any changes to the session through to the database as the request exits the server. Sessions must obey the Serialization contract, and servlets must call the Session.setAttribute() method to ensure that changes are persisted.
Line 12: Line 14:
 
* The session ID manager ensures that session IDs are unique across all webapps hosted on a Jetty instance, and thus there can only be one session ID manager per Jetty instance.  
 
* The session ID manager ensures that session IDs are unique across all webapps hosted on a Jetty instance, and thus there can only be one session ID manager per Jetty instance.  
 
* The session manager handles the session lifecycle (create/update/invalidate/expire) on behalf of a web application, so there is one session manager per web application instance.  
 
* The session manager handles the session lifecycle (create/update/invalidate/expire) on behalf of a web application, so there is one session manager per web application instance.  
These managers also cooperate and collaborate with the org.eclipse.jetty.handler.SessionHandler to enable cross-context dispatch.
+
These managers also cooperate and collaborate with the <code>org.eclipse.jetty.server.session.SessionHandler</code> to enable cross-context dispatch.
  
 
===Configuring the JDBCSessionIdManager===
 
===Configuring the JDBCSessionIdManager===
  
You need to configure an org.eclipse.jetty.servlet.JDBCSessionIdManager instance, either in embedded code or in a jetty.xml file. Here is an example of a jetty.xml setup:
+
You need to configure an <code>org.eclipse.jetty.server.session.JDBCSessionIdManager</code> instance, either in embedded code or in a <code>jetty.xml</code> file. Here is an example of a <code>jetty.xml</code> setup:
  
 
<source lang="xml">
 
<source lang="xml">
 
  <Set name="sessionIdManager">
 
  <Set name="sessionIdManager">
     <New id="jdbcidmgr" class="org.eclipse.jetty.servlet.JDBCSessionIdManager">
+
     <New id="jdbcidmgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager">
 
         <Arg><Ref id="Server"/></Arg>
 
         <Arg><Ref id="Server"/></Arg>
 
         <Set name="workerName">fred</Set>
 
         <Set name="workerName">fred</Set>
Line 33: Line 35:
 
</source>
 
</source>
  
Notice that the JDBCSessionIdManager needs access to a database. The jetty.xml above configures it with the name of a javax.sql.DataSource that is defined elsewhere. Consult [/display/JETTY/JNDI Jetty Naming Resources] for more information on how to configure database access with Jetty. If you don't want to use a DataSource, you can configure JDBC Driver information instead. Here's an example:
+
Notice that the JDBCSessionIdManager needs access to a database. The <code>jetty.xml</code> above configures it with the name of a <code>javax.sql.DataSource</code> that is defined elsewhere. Consult [[Jetty/Feature/JNDI|Jetty Naming Resources]] for more information on how to configure database access with Jetty. If you don't want to use a DataSource, you can configure JDBC Driver information instead. Here's an example:
  
 
<source lang="xml">
 
<source lang="xml">
 
  <Set name="sessionIdManager">
 
  <Set name="sessionIdManager">
     <New id="jdbcidmgr" class="org.eclipse.jetty.servlet.JDBCSessionIdManager">
+
     <New id="jdbcidmgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager">
 
         <Arg><Ref id="Server"/></Arg>
 
         <Arg><Ref id="Server"/></Arg>
 
         <Set name="workerName">fred</Set>
 
         <Set name="workerName">fred</Set>
Line 53: Line 55:
 
</source>
 
</source>
  
As Jetty configuration files are direct mappings of XML to Java, it is straightforward to see how this would be done in code, but here's an example anyway:
+
As Jetty configuration files are direct mappings of XML to Java, it is straightforward to see how to do this in code, but here's an example anyway:
  
 
<source lang="java">
 
<source lang="java">
Line 67: Line 69:
 
</source>
 
</source>
  
You must configure the JDBCSessionIdManager with a '''workerName''' that is unique across the cluster. Typically the name relates to the physical node on which the instance is executing. If this name is not unique, your load balancer might fail to distribute your sessions correctly.
+
You must configure the JDBCSessionIdManager with a <code>workerName</code> that is unique across the cluster. Typically the name relates to the physical node on which the instance is executing. If this name is not unique, your load balancer might fail to distribute your sessions correctly.
  
You can also configure how often the persistent session mechanism sweeps the database looking for old, expired sessions with the '''scavengeInterval''' setting. By default, this is set to '''60seconds'''. We recommend that you do not increase the frequency as you will increase the load on the database with very little gain, as old, expired sessions can harmlessly sit in the database.
+
You can also configure how often the persistent session mechanism sweeps the database looking for old, expired sessions with the <code>scavengeInterval</code> setting. The default value is 60 seconds. We recommend that you not increase the frequency because doing so increases the load on the database with very little gain; old, expired sessions can harmlessly sit in the database.
  
 
===Configuring a JDBCSessionManager===
 
===Configuring a JDBCSessionManager===
  
The way you configure a JDBCSessionManager is a depends on whether you're configuring from a context xml file or a jetty-web.xml file, or code. The basic difference is how you get a reference to the Jetty org.eclipse.jetty.server.Jetty instance.
+
The way you configure a JDBCSessionManager depends on whether you're configuring from a context xml file or a <code>jetty-web.xml</code> file or code. The basic difference is how you get a reference to the <code>Jetty org.eclipse.jetty.server.Jetty</code> instance.
  
From a context xml file, you reference the Server instance as a ''Ref'':
+
From a context xml file, you reference the Server instance as a <code>Ref</code>:
  
 
<source lang="xml">
 
<source lang="xml">
Line 86: Line 88:
 
   
 
   
 
  <Set name="sessionHandler">
 
  <Set name="sessionHandler">
     <New class="org.eclipse.jetty.servlet.SessionHandler">
+
     <New class="org.eclipse.jetty.server.session.SessionHandler">
 
       <Arg>
 
       <Arg>
         <New id="jdbcmgr" class="org.eclipse.jetty.servlet.JDBCSessionManager">
+
         <New id="jdbcmgr" class="org.eclipse.jetty.server.session.JDBCSessionManager">
 
           <Set name="idManager">
 
           <Set name="idManager">
 
             <Ref id="jdbcIdMgr"/>
 
             <Ref id="jdbcIdMgr"/>
Line 99: Line 101:
 
</source>
 
</source>
  
From a WEB-INF/jetty-web.xml file, you can reference the Server instance directly:
+
From a <code>WEB-INF/jetty-web.xml</code> file, you can reference the Server instance directly:
  
 
<source lang="xml">
 
<source lang="xml">
Line 107: Line 109:
 
  </Get>
 
  </Get>
 
  <Set name="sessionHandler">
 
  <Set name="sessionHandler">
     <New class="org.eclipse.jetty.servlet.SessionHandler">
+
     <New class="org.eclipse.jetty.server.session.SessionHandler">
 
       <Arg>
 
       <Arg>
         <New class="org.eclipse.jetty.servlet.JDBCSessionManager">
+
         <New class="org.eclipse.jetty.server.session.JDBCSessionManager">
 
           <Set name="idManager">
 
           <Set name="idManager">
 
             <Ref id="jdbcIdMgr"/>
 
             <Ref id="jdbcIdMgr"/>

Revision as of 16:05, 23 April 2013

Contents

Session Clustering using a Database


Jetty can support session clustering by persisting sessions to a shared database. Each Jetty instance locally caches sessions for which it has received requests, writing any changes to the session through to the database as the request exits the server. Sessions must obey the Serialization contract, and servlets must call the Session.setAttribute() method to ensure that changes are persisted.

The persistent session mechanism works in conjunction with a load balancer that supports stickiness. Stickiness can be based on various data items, such as source IP address or characteristics of the session ID or a load-balancer specific mechanism. For those load balancers that examine the session ID, the Jetty persistent session mechanism appends a node ID to the session ID, which can be used for routing.

In this type of solution, the database can become both a bottleneck and a single point of failure. Jetty takes steps to reduce the load on the database (discussed below), but in a heavily loaded environment you might need to investigate other optimization strategies such as local caching and database replication. You should also consult your database vendor's documentation for information on how to ensure high availability and failover of your database.

Configuration

There are two components to session management in Jetty: a session ID manager and a session manager.

  • The session ID manager ensures that session IDs are unique across all webapps hosted on a Jetty instance, and thus there can only be one session ID manager per Jetty instance.
  • The session manager handles the session lifecycle (create/update/invalidate/expire) on behalf of a web application, so there is one session manager per web application instance.

These managers also cooperate and collaborate with the org.eclipse.jetty.server.session.SessionHandler to enable cross-context dispatch.

Configuring the JDBCSessionIdManager

You need to configure an org.eclipse.jetty.server.session.JDBCSessionIdManager instance, either in embedded code or in a jetty.xml file. Here is an example of a jetty.xml setup:

 <Set name="sessionIdManager">
     <New id="jdbcidmgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager">
         <Arg><Ref id="Server"/></Arg>
         <Set name="workerName">fred</Set>
         <Set name="DatasourceName">javax.sql.DataSource/default</Set>
         <Set name="scavengeInterval">60</Set>
     </New>
 </Set>
 <Call name="setAttribute">
       <Arg>jdbcIdMgr</Arg>
       <Arg><Ref id="jdbcidmgr"/></Arg>
 </Call>

Notice that the JDBCSessionIdManager needs access to a database. The jetty.xml above configures it with the name of a javax.sql.DataSource that is defined elsewhere. Consult Jetty Naming Resources for more information on how to configure database access with Jetty. If you don't want to use a DataSource, you can configure JDBC Driver information instead. Here's an example:

 <Set name="sessionIdManager">
     <New id="jdbcidmgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager">
         <Arg><Ref id="Server"/></Arg>
         <Set name="workerName">fred</Set>
         <Call name="setDriverInfo">
           <Arg>com.mysql.jdbc.Driver</Arg>
           <Arg>jdbc:mysql://127.0.0.1:3306/sessions?user=janb</Arg>
         </Call>
         <Set name="scavengeInterval">60</Set>
       </New>
 </Set>
 <Call name="setAttribute">
       <Arg>jdbcIdMgr</Arg>
       <Arg><Ref id="jdbcidmgr"/></Arg>
 </Call>

As Jetty configuration files are direct mappings of XML to Java, it is straightforward to see how to do this in code, but here's an example anyway:

 Server server = new Server();
     ...
 JDBCSessionIdManager idMgr = new JDBCSessionIdManager(server);
 idMgr.setWorkerName("fred");
 idMgr.setDriverInfo("com.mysql.jdbc.Driver", "jdbc:mysql://127.0.0.1:3306/sessions?user=janb");
 idMgr.setScavengeInterval(60);
 server.setSessionIdManager(idMgr);

You must configure the JDBCSessionIdManager with a workerName that is unique across the cluster. Typically the name relates to the physical node on which the instance is executing. If this name is not unique, your load balancer might fail to distribute your sessions correctly.

You can also configure how often the persistent session mechanism sweeps the database looking for old, expired sessions with the scavengeInterval setting. The default value is 60 seconds. We recommend that you not increase the frequency because doing so increases the load on the database with very little gain; old, expired sessions can harmlessly sit in the database.

Configuring a JDBCSessionManager

The way you configure a JDBCSessionManager depends on whether you're configuring from a context xml file or a jetty-web.xml file or code. The basic difference is how you get a reference to the Jetty org.eclipse.jetty.server.Jetty instance.

From a context xml file, you reference the Server instance as a Ref:

 <Ref name="Server" id="Server">
   <Call id="jdbcIdMgr" name="getAttribute">
     <Arg>jdbcIdMgr</Arg>
   </Call>
 </Ref>
 
 <Set name="sessionHandler">
    <New class="org.eclipse.jetty.server.session.SessionHandler">
      <Arg>
        <New id="jdbcmgr" class="org.eclipse.jetty.server.session.JDBCSessionManager">
          <Set name="idManager">
            <Ref id="jdbcIdMgr"/>
          </Set>
        </New>
      </Arg>
    </New>
 </Set>

From a WEB-INF/jetty-web.xml file, you can reference the Server instance directly:

 
 <Get name="server">
    <Get id="jdbcIdMgr" name="sessionIdManager"/>
 </Get>
 <Set name="sessionHandler">
    <New class="org.eclipse.jetty.server.session.SessionHandler">
      <Arg>
        <New class="org.eclipse.jetty.server.session.JDBCSessionManager">
          <Set name="idManager">
            <Ref id="jdbcIdMgr"/>
          </Set>
        </New>
      </Arg>
    </New>
 </Set>

If you're embedding this in code:

 
 //assuming you have already set up the JDBCSessionIdManager as shown earlier
 //and have a reference to the Server instance:
 
 WebAppContext wac = new WebAppContext();
  ... //configure your webapp context
 JDBCSessionManager jdbcMgr = new JDBCSessionManager();
 jdbcMgr.setIdManager(server.getSessionIdManager());
 wac.setSessionHandler(jdbcMgr);