blob: db704523626483add7631d0862b2a36d9d699d3a [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Session Clustering with a Database</title><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><meta name="keywords" content="jetty, servlet-api, cometd, http, spdy, eclipse, maven, java, software"><link rel="home" href="index.html" title="Jetty : The Definitive Reference"><link rel="up" href="session-management.html" title="Chapter&nbsp;11.&nbsp;Session Management"><link rel="prev" href="using-persistent-sessions.html" title="Using Persistent Sessions"><link rel="next" href="session-clustering-mongodb.html" title="Session Clustering with MongoDB"><link xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" rel="shortcut icon" href="images/favicon.ico"><script type="text/javascript" src="js/shCore.js"></script><script type="text/javascript" src="js/shBrushJava.js"></script><script type="text/javascript" src="js/shBrushXml.js"></script><script type="text/javascript" src="js/shBrushBash.js"></script><script type="text/javascript" src="js/shBrushJScript.js"></script><script type="text/javascript" src="js/shBrushSql.js"></script><script type="text/javascript" src="js/shBrushProperties.js"></script><script type="text/javascript" src="js/shBrushPlain.js"></script><link type="text/css" rel="stylesheet" href="css/shCore.css"><link type="text/css" rel="stylesheet" href="css/shThemeEclipse.css"><link type="text/css" rel="stylesheet" href="css/font-awesome.min.css"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><tr><td style="width: 25%"><a href="http://www.eclipse.org/jetty"><img src="images/jetty-header-logo.png" alt="Jetty Logo"></a><br><span style="font-size: small">
Version: 9.0.6.v20130930</span></td><td style="width: 50%"><script type="text/javascript"> (function() {
var cx = '016459005284625897022:obd4lsai2ds';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script><gcse:search></gcse:search></td></tr></table><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Session Clustering with a Database</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="using-persistent-sessions.html"><i class="icon-chevron-left"></i> Previous</a>&nbsp;</td><th width="60%" align="center">Chapter&nbsp;11.&nbsp;Session Management<br><a accesskey="p" href="index.html"><i class="icon-home"></i> Home</a></th><td width="20%" align="right">&nbsp;<a accesskey="n" href="session-clustering-mongodb.html">Next <i class="icon-chevron-right"></i></a></td></tr></table><hr></div><div xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" class="jetty-callout"><h5 class="callout"><a href="http://www.webtide.com/support.jsp">Contact the core Jetty developers at
<span class="website">www.webtide.com</span></a></h5><p>
private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ...
scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="session-clustering-jdbc"></a>Session Clustering with a Database</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="session-clustering-jdbc.html#d0e7965">Configuration</a></span></dt><dt><span class="section"><a href="session-clustering-jdbc.html#d0e7982">Configuring the JDBCSessionIdManager</a></span></dt><dt><span class="section"><a href="session-clustering-jdbc.html#d0e8016">Configuring the JDBCSessionManager</a></span></dt></dl></div><p>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.</p><p>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.</p><p>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.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="d0e7965"></a>Configuration</h3></div></div></div><p>There are two components to session management in Jetty: a session
ID manager and a session manager.</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>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.</p></li><li class="listitem"><p>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.</p></li></ul></div><p>These managers also cooperate and collaborate with the
<code class="code">org.eclipse.jetty.server.session.SessionHandler</code> to enable
cross-context dispatch.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="d0e7982"></a>Configuring the JDBCSessionIdManager</h3></div></div></div><p>You need to configure an
<code class="code">org.eclipse.jetty.server.session.JDBCSessionIdManager</code>
instance, either in embedded code or in a <code class="filename">jetty.xml</code>
file. Here is an example of a jetty.xml setup:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<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>
]]>
</script></div><p>Notice that the JDBCSessionIdManager needs access to a database. The
<code class="filename">jetty.xml</code> above configures it with the name of a
<code class="code">javax.sql.DataSource</code> 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:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<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>
]]>
</script></div><p>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:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false">
<![CDATA[
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);
]]>
</script></div><p>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.</p><p>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 10mins. 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.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="d0e8016"></a>Configuring the JDBCSessionManager</h3></div></div></div><p>The way you configure a JDBCSessionManager depends on whether you're
configuring from a context xml file or a
<code class="filename">jetty-web.xml</code> file or code. The basic difference is
how you get a reference to the Jetty
<code class="code">org.eclipse.jetty.server.Server</code> instance.</p><p>From a context xml file, you reference the Server instance as a
Ref:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<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>
]]>
</script></div><p>From a <code class="filename">WEB-INF/jetty-web.xml</code> file, you can
reference the Server instance directly:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: xml;toolbar: false">
<![CDATA[
<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>
]]>
</script></div><p>If you're embedding this in code:</p><div class="informalexample"><script type="syntaxhighlighter" class="brush: java;toolbar: false">
<![CDATA[
//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);
]]>
</script></div></div></div><script type="text/javascript">
SyntaxHighlighter.all()
</script><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="using-persistent-sessions.html"><i class="icon-chevron-left"></i> Previous</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="session-management.html"><i class="icon-chevron-up"></i> Top</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="session-clustering-mongodb.html">Next <i class="icon-chevron-right"></i></a></td></tr><tr><td width="40%" align="left" valign="top">Using Persistent Sessions&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html"><i class="icon-home"></i> Home</a></td><td width="40%" align="right" valign="top">&nbsp;Session Clustering with MongoDB</td></tr></table></div><p xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times"><div class="jetty-callout">
See an error or something missing?
<span class="callout"><a href="http://github.com/jetty-project/jetty-documentation">Contribute to this documentation at
<span class="website"><i class="icon-github"></i> Github!</span></a></span><span style="float: right"><i>(Generated: 2013-10-30T13:20:26-05:00)</i></span></div></p><script xmlns:jfetch="java:org.eclipse.jetty.xslt.tools.JavaSourceFetchExtension" xmlns:fetch="java:org.eclipse.jetty.xslt.tools.SourceFetchExtension" xmlns:d="http://docbook.org/ns/docbook" xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0" xmlns:xslthl="http://xslthl.sf.net" xmlns:gcse="http://www.google.com" xmlns:date="http://exslt.org/dates-and-times" type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1149868-7']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script></body></html>