![]() Version: 9.3.10.M0 |
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
Jetty can support session clustering by persisting sessions into MongoDB. Each Jetty instance locally caches sessions for which it has received requests, writing any changes to the session through to the cluster 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 session persistence 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 traffic on the network needs to be carefully watched and tends to be the bottleneck. You are probably investigating this solution in order to scale to large amount of users and sessions, so careful attention should be paid to your usage scenario. Applications with a heavy write profile to their sessions will consume more network bandwidth than profiles that are predominately read oriented. We recommend using this session manager with largely read based session scenarios.
There are two components to session management in Jetty: a session ID manager and a session manager.
These managers also cooperate and collaborate with the
org.eclipse.jetty.server.session.SessionHandler
to enable
cross-context dispatch.
When using the jetty distribution, to enable the mongodb session persistence mechanism, you will first need to enable the nosql module for your base using the --add-to-start or --add-to-startd argument to the start.jar. This module will automatically download the mongodb-java-driver and install it to your base’s lib/nosql directory.
As part of the module installation, the necessary mongo java driver jars
will be dynamically downloaded and installed to your
${jetty.base}/lib/nosql
directory. If you need to up or downgrade the
version of these jars, then you can delete the jars that were
automatically installed and replace them. Once you’ve done that, you
will need to prevent jetty’s startup checks from detecting the missing
jars. To do that, you can use --skip-file-validation=nosql
argument to
start.jar on the command line, or place that line inside
${jetty.base}/start.ini
to ensure it is used for every start.
You will also find the following properties, either in your base’s start.d/nosql.ini file or appended to your start.ini, depending on how you enabled the module:
## Unique identifier for this node in the cluster jetty.nosqlSession.workerName=node1 ## Interval in seconds between scavenging expired sessions jetty.nosqlSession.scavenge=1800
The jetty.nosqlSession.workerName
is the unique name for this jetty
Server instance. It will be used by the sticky load balancer to uniquely
identify the node. You should change this value on each node to which
you install mongodb session management.
The jetty.nosqlSession.scavenge
property defines the time in seconds
between runs of the scavengeer: the scavenger is a task which runs
periodically to clean out sessions that have expired but become stranded
in the database for whatever reason.
These properties are substituted into the configuration of the MongoDBSessionIdManager and MongoSessionManager.
The nosql module will have installed file called $\{jetty.home}/etc/jetty-nosql.xml. This file configures an instance of the MongoSessionIdManager that will be shared across all webapps deployed on that server. It looks like this:
Unresolved directive in administration/sessions/session-clustering-mongodb.adoc - include::/home/jesse/src/jetty.project/target/checkout/jetty-documentation/../jetty-nosql/src/main/config/etc/jetty-mongo-session-store.xml[]
The MongoSessionIdManager needs access to a mongodb cluster, and the jetty-nosql.xml file assumes the defaults of localhost and default mongodb port. If you need to configure something else, you will need to edit this file. Here’s an example of a more complex setup to use a remote mongodb instance:
<New id="mongodb" class="com.mongodb.Mongo">
<Arg>
<New class="java.util.ArrayList">
<Call name="add">
<Arg>
<New class="com.mongodb.ServerAddress">
<Arg type="java.lang.String">foo.example.com</Arg>
<Arg type="int">27017</Arg>
</New>
</Arg>
</Call>
<!-- Add more Call statements here as desired --> </New>
</Arg>
<Call name="getDB">
<Arg>HttpSessions</Arg>
<Call id="sessionDocument" name="getCollection">
<Arg>sessions</Arg>
</Call>
</Call>
<!-- If you want to configure Jetty to be able to read through the slaves, call the following: -->
<Call name="slaveOk"/>
</New>
<Set name="sessionIdManager">
<New id="mongoIdMgr" class="org.eclipse.jetty.nosql.mongodb.MongoSessionIdManager">
<Arg>
<Ref id="Server"/>
</Arg>
<Arg>
<Ref id="sessionDocument"/>
</Arg>
<Set name="workerName"><Property name="jetty.nosqlSession.workerName" default="node1"/></Set>
<Set name="scavengePeriod"><Property name="jetty.nosqlSession.scavenge" default="1800"/></Set>
</New>
</Set>
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();
...
MongoSessionIdManager idMgr = newMongoSessionIdManager(server);
idMgr.setWorkerName("node1");
idMgr.setScavengePeriod(1800);
server.setSessionIdManager(idMgr);
The MongoSessionIdManager has slightly different options than some of our more traditional session options. The MongoDBSessionIdManager has the same scavenge timers which govern the setting of a valid session to invalid after a certain period of inactivity. New to this session id manager is the extra purge setting which governs removal from the mongodb cluster. This can be configured through the purge option. Purge is by default set to true and by default runs daily for each node on the cluster. Also able to be configured is the age in which an invalid session will be retained which is set to 1 day by default. This means that invalid sessions will be removed after lingering in the mongodb instance for a day. There is also an option for purging valid sessions that have not been used recently. The default time for this is 1 week. You can disable these behaviors by setting purge to false.
true
.As mentioned elsewhere, there should be one MongoSessionManager per context (ie webapp). It will need to reference the single MongoSessionIdManager configured previously for the Server.
The way you configure a
org.eclipse.jetty.nosql.mongodb.MongoSessionManager
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.Server
instance.
From a context xml file, you reference the Server instance as a Ref:
<Ref name="Server" id="Server">
<Call id="mongoIdMgr" name="getSessionIdManager"/>
</Ref>
<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler">
<Arg>
<New id="mongoMgr" class="org.eclipse.jetty.nosql.mongodb.MongoSessionManager">
<Set name="sessionIdManager">
<Ref id="mongoIdMgr"/>
</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="mongoIdMgr" name="sessionIdManager"/>
</Get>
<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler">
<Arg>
<New class="org.eclipse.jetty.nosql.mongodb.MongoSessionManager">
<Set name="sessionIdManager">
<Ref id="mongoIdMgr"/>
</Set>
</New>
</Arg>
</New>
</Set>
If you’re embedding this in code:
//assuming you have already set up the MongoSessionIdManager as shown earlier
//and have a reference to the Server instance:
WebAppContext wac = new WebAppContext();
... //configure your webapp context
MongoSessionManager mongoMgr = new MongoSessionManager();
mongoMgr.setSessionIdManager(server.getSessionIdManager());
wac.setSessionHandler(new SessionHandler(mongoMgr));