blob: 3e38678bdbf9f5a6df5ae02186bbce830791eb51 [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 Stylesheets V1.79.1"><meta name="keywords" content="jetty, servlet, servlet-api, cometd, http, websocket, eclipse, maven, java, server, software"><link rel="home" href="index.html" title="Jetty"><link rel="up" href="session-management.html" title="Chapter&nbsp;10.&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"><link rel="stylesheet" href="css/highlighter/foundation.css"><script src="js/highlight.pack.js"></script><script>
hljs.initHighlightingOnLoad();
</script><link type="text/css" rel="stylesheet" href="css/font-awesome/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.3.28.v20191105</span></td><td style="width: 50%"></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="fa fa-chevron-left" aria-hidden="true"></i> Previous</a>&nbsp;</td><th width="60%" align="center">Chapter&nbsp;10.&nbsp;Session Management<br><a accesskey="p" href="index.html"><i class="fa fa-home" aria-hidden="true"></i> Home</a></th><td width="20%" align="right">&nbsp;<a accesskey="n" href="session-clustering-mongodb.html">Next <i class="fa fa-chevron-right" aria-hidden="true"></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/">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 for sponsored feature development
</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 class="toc"><dt><span class="section"><a href="session-clustering-jdbc.html#_configuration">Configuration</a></span></dt><dt><span class="section"><a href="session-clustering-jdbc.html#_the_jdbc_session_module">The jdbc-session Module</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 <code class="literal">Session.setAttribute()</code> 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&#8217;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="_configuration"></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" style="list-style-type: disc; "><li class="listitem">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.</li><li class="listitem">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.</li></ul></div><p>These managers also cooperate and collaborate with the <code class="literal">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="_the_jdbc_session_module"></a>The jdbc-session Module</h3></div></div></div><p>When using the jetty distribution, to enable jdbc session persistence, you will first need to enable the jdbc-session <a class="link" href="startup-modules.html" title="Managing Startup Modules">module</a> for your <a class="link" href="quickstart-running-jetty.html#creating-jetty-base" title="Creating a new Jetty Base">base</a> using the <code class="literal">--add-to-start</code> or <code class="literal">--add-to-startd</code> argument to the <a class="link" href="startup.html#startup-overview" title="Startup Overview">start.jar</a>.</p><p>You will also find the following properties, either in your base&#8217;s start.d/jdbc-session.ini file or appended to your start.ini, depending on how you enabled the module:</p><pre 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"><code>## Unique identifier for this node in the cluster
jetty.jdbcSession.workerName=node1
##Uncomment either the datasource name or driverClass and connectionURL
#jetty.jdbcSession.datasource=sessions
jetty.jdbcSession.driverClass=org.apache.derby.jdbc.EmbeddedDriver
jetty.jdbcSession.connectionURL=jdbc:derby:sessions;create=true</code></pre><div class="variablelist"><dl class="variablelist"><dt><span class="term">jetty.jdbcSession.workerName</span></dt><dd>The name that uniquely identifies this node in the cluster.
This value will also be used by the sticky load balancer to identify the node.
Don&#8217;t forget to change the value of this property on <span class="strong"><strong>each</strong></span> node on which you enable jdbc session clustering.</dd><dt><span class="term">jetty.jdbcSession.scavenge</span></dt><dd>The time in seconds between sweeps of a task which scavenges old expired sessions.
The default is 10 minutess.
Increasing the frequency is not recommended as doing so increases the load on the database with very little gain.</dd><dt><span class="term">jetty.jdbcSession.datasource</span></dt><dd>The name of a <code class="literal">javax.sql.DataSource</code> that gives access to the database that holds the session information.
You should configure <span class="strong"><strong>either</strong></span> this or the jdbc driver information described next.</dd><dt><span class="term">jetty.jdbcSession.datasource and jetty.jdbcSession.connectionURL</span></dt><dd>This is the name of the jdbc driver class, and a jdbc connection url suitable for that driver.
You should configure <span class="strong"><strong>either</strong></span> this or the jdbc datasource name described above.</dd></dl></div><p>These properties are applied to the <code class="literal">JDBCSessionIdManager</code> described below.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_configuring_the_jdbcsessionidmanager"></a>Configuring the JDBCSessionIdManager</h4></div></div></div><p>The jdbc-session module will have installed file called <code class="literal">$\{jetty.home}/etc/jetty-jdbc-sessions.xml</code>.
This file configures an instance of the <code class="literal">JDBCSessionIdManager</code> that will be shared across all webapps deployed on that server.
It looks like this:</p><pre 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"><code>&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;!-- ===================================================================== --&gt;
&lt;!-- Configure a SessionIdManager --&gt;
&lt;!-- ===================================================================== --&gt;
&lt;Set name="sessionIdManager"&gt;
&lt;New id="idMgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager"&gt;
&lt;Arg&gt;
&lt;Ref refid="Server"/&gt;
&lt;/Arg&gt;
&lt;Set name="workerName"&gt;&lt;Property name="jetty.jdbcSession.workerName" default="node1"/&gt;&lt;/Set&gt;
&lt;Set name="scavengeInterval"&gt;&lt;Property name="jetty.jdbcSession.scavenge" default="1800"/&gt;&lt;/Set&gt;
&lt;!-- ===================================================================== --&gt;
&lt;!-- Uncomment either the datasource or driver setup and configure --&gt;
&lt;!-- ===================================================================== --&gt;
&lt;!--
&lt;Set name="DatasourceName"&gt;&lt;Property name="jetty.jdbcSession.datasource" default="javax.sql.DataSource/default"/&gt;&lt;/Set&gt;
--&gt;
&lt;!--
&lt;Call name="setDriverInfo"&gt;
&lt;Arg&gt;&lt;Property name="jetty.jdbcSession.driverClass"/&gt;&lt;/Arg&gt;
&lt;Arg&gt;&lt;Property name="jetty.jdbcSession.connectionURL"/&gt;&lt;/Arg&gt;
&lt;/Call&gt;
--&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Configure&gt;</code></pre><p>As well as uncommenting and setting up appropriate values for the properties discussed above, you will also need to edit this file and uncomment <span class="strong"><strong>either</strong></span> the data source or the driver info elements.</p><p>As Jetty configuration files are direct mappings of XML to Java, it is straight forward to do this in code:</p><pre 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"><code>Server server = new Server();
...
JDBCSessionIdManager idMgr = new JDBCSessionIdManager(server);
idMgr.setWorkerName("node1");
idMgr.setDriverInfo("com.mysql.jdbc.Driver", "jdbc:mysql://127.0.0.1:3306/sessions?user=janb");
idMgr.setScavengeInterval(600);
server.setSessionIdManager(idMgr);</code></pre><div class="section"><div class="titlepage"><div><div><h5 class="title"><a name="_configuring_the_database_schema"></a>Configuring the Database Schema</h5></div></div></div><p>You may find it necessary to change the names of the tables and columns that the JDBC Session management uses to store the session information.
The defaults used are:</p><div class="table"><a name="d0e10488"></a><p class="title"><b>Table&nbsp;10.2.&nbsp;Default Values for Session Id Table</b></p><div class="table-contents"><table class="table" summary="Default Values for Session Id Table" border="1"><colgroup><col class="col_1"><col class="col_2"></colgroup><thead><tr><th align="left" valign="top">table name</th><th align="left" valign="top">JettySessionIds</th></tr></thead><tbody><tr><td align="left" valign="top"><p>columns</p></td><td align="left" valign="top"><p>id</p></td></tr></tbody></table></div></div><br class="table-break"><div class="table"><a name="d0e10508"></a><p class="title"><b>Table&nbsp;10.3.&nbsp;Default Values for Session Table</b></p><div class="table-contents"><table class="table" summary="Default Values for Session Table" border="1"><colgroup><col class="col_1"><col class="col_2"></colgroup><thead><tr><th align="left" valign="top">table name</th><th align="left" valign="top">JettySessions</th></tr></thead><tbody><tr><td align="left" valign="top"><p>columns</p></td><td align="left" valign="top"><p>rowId, sessionId, contextPath, virtualHost, lastNode,
accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime,
expiryTime, maxInterval, map</p></td></tr></tbody></table></div></div><br class="table-break"><p>To change these values, use the <a class="link" href="http://www.eclipse.org/jetty/javadoc/9.3.28.v20191105/org/eclipse/jetty/server/session/SessionIdTableSchema.html" target="_top">org.eclipse.jetty.server.session.SessionIdTableSchema</a> and <a class="link" href="http://www.eclipse.org/jetty/javadoc/9.3.28.v20191105/org/eclipse/jetty/server/session/SessionTableSchema.html" target="_top">org.eclipse.jetty.server.session.SessionTableSchema</a> classes.
These classes have getter/setter methods for the table name and all columns.</p><p>Here&#8217;s an example of changing the name of <code class="literal">JettySessionsId</code> table and its single column.
This example will use java code, but as explained above, you may also do this via a Jetty xml configuration file:</p><pre 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"><code>JDBCSessionIdManager idManager = new JDBCSessionIdManager(server);
SessionIdTableSchema idTableSchema = new SessionIdTableSchema();
idTableSchema.setTableName("mysessionids");
idTableSchema.setIdColumn("theid");
idManager.setSessionIdTableSchema(idTableSchema);</code></pre><p>In a similar fashion, you can change the names of the table and columns for the <code class="literal">JettySessions</code> table.
<span class="strong"><strong>Note</strong></span> that both the <code class="literal">SessionIdTableSchema</code> and the <code class="literal">SessionTableSchema</code> instances are set on the <code class="literal">JDBCSessionIdManager</code> class.</p><pre 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"><code>JDBCSessionIdManager idManager = new JDBCSessionIdManager(server);
SessionTableSchema sessionTableSchema = new SessionTableSchema();
sessionTableSchema.setTableName("mysessions");
sessionTableSchema.setIdColumn("mysessionid");
sessionTableSchema.setAccessTimeColumn("atime");
sessionTableSchema.setContextPathColumn("cpath");
sessionTableSchema.setCookieTimeColumn("cooktime");
sessionTableSchema.setCreateTimeColumn("ctime");
sessionTableSchema.setExpiryTimeColumn("extime");
sessionTableSchema.setLastAccessTimeColumn("latime");
sessionTableSchema.setLastNodeColumn("lnode");
sessionTableSchema.setLastSavedTimeColumn("lstime");
sessionTableSchema.setMapColumn("mo");
sessionTableSchema.setMaxIntervalColumn("mi");
idManager.setSessionTableSchema(sessionTableSchema);</code></pre></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_configuring_the_jdbcsessionmanager"></a>Configuring the JDBCSessionManager</h4></div></div></div><p>As mentioned elsewhere, there should be one <code class="literal">JDBCSessionManager</code> per context (e.g. webapp).
It will need to reference the single <code class="literal">JDBCSessionIdManager</code> configured previously for the Server.</p><p>The way you configure a <code class="literal">JDBCSessionManager</code> depends on whether you&#8217;re configuring from a context xml file, a <code class="literal">jetty-web.xml</code> file or code.
The basic difference is how you get a reference to the Jetty <code class="literal">org.eclipse.jetty.server.Server</code> instance.</p><p>From a context xml file, you reference the Server instance as a Ref:</p><pre 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"><code> &lt;Ref id="Server"&gt;
&lt;Call id="idMgr" name="getSessionIdManager"/&gt;
&lt;/Ref&gt;
&lt;Set name="sessionHandler"&gt;
&lt;New class="org.eclipse.jetty.server.session.SessionHandler"&gt;
&lt;Arg&gt;
&lt;New id="jdbcmgr" class="org.eclipse.jetty.server.session.JDBCSessionManager"&gt;
&lt;Set name="sessionIdManager"&gt;
&lt;Ref id="idMgr"/&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Set&gt;</code></pre><p>From a <code class="literal">WEB-INF/jetty-web.xml</code> file, you can reference the Server instance directly:</p><pre 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"><code>&lt;Get name="server"&gt;
&lt;Get id="idMgr" name="sessionIdManager"/&gt;
&lt;/Get&gt;
&lt;Set name="sessionHandler"&gt;
&lt;New class="org.eclipse.jetty.server.session.SessionHandler"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.server.session.JDBCSessionManager"&gt;
&lt;Set name="sessionIdManager"&gt;
&lt;Ref id="idMgr"/&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Set&gt;</code></pre><p>If you&#8217;re embedding this in code:</p><pre 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"><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.setSessionIdManager(server.getSessionIdManager());
SessionHandler sessionHandler = new SessionHandler(jdbcMgr);
wac.setSessionHandler(sessionHandler);</code></pre></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="fa fa-chevron-left" aria-hidden="true"></i> Previous</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="session-management.html"><i class="fa fa-chevron-up" aria-hidden="true"></i> Top</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="session-clustering-mongodb.html">Next <i class="fa fa-chevron-right" aria-hidden="true"></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="fa fa-home" aria-hidden="true"></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/eclipse/jetty.project">Contribute to this documentation at
<span class="website"><i class="fa fa-github" aria-hidden="true"></i> Github!</span></a></span><span style="float: right"><i>(Generated: 2019-11-05)</i></span></div></p></body></html>