Updates to session documentation.

Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
Jan Bartel 2020-09-10 13:51:44 +02:00
parent 6117578f38
commit d12193990a
8 changed files with 87 additions and 39 deletions

View File

@ -16,7 +16,7 @@
// ========================================================================
//
[[op-session-base]]
[[ops-session-base]]
=== The Base Sessions Module
The `sessions` module is the base module that all other session modules depend upon.
As such it will be _transitively_ enabled if you enable any of the other session modules: you need to _explicitly_ enable it if you wish to _change_ any settings from their defaults.
@ -24,26 +24,50 @@ As such it will be _transitively_ enabled if you enable any of the other session
Enabling the `sessions` module puts the `$jetty.home/etc/sessions/id-manager.xml` file onto the execution path and generates a `$jetty.base/start.d/sessions.ini` file.
The `id-manager.xml` file instantiates a `DefaultSessionIdManager` and `HouseKeeper`.
The former is used to generate and manage session ids whilst the latter is responsible for periodic scavenging of expired sessions.
The `sessions.ini` file can be used to configure them.
The former is used to generate and manage session ids whilst the latter is responsible for periodic xref:ops-session-base-scavenge[scavenging] of expired sessions.
==== Configuration
The `start.d/sessions.ini` file contains thse configuration properties:
jetty.sessionIdManager.workerName::
This uniquely identifies the jetty server instance within a cluster.
If you have more than one Jetty instance, it is *crucial* that you configure the worker name differently on each jetty instance.
You can either provide a value for this property, or you can allow jetty to try and synthesize a workerName - the latter option is _only_ advisable in the case of a single, non-clustered deployment.
There are two ways jetty will try to synthesize a default `workerName`:
This uniquely identifies the jetty server instance and is applied to the `SessionIdManager`.
You can either provide a value for this property, or you can allow Jetty to try and synthesize a `workerName` - the latter option is _only_ advisable in the case of a single, non-clustered deployment.
There are two ways a default `workerName` can be synthesized:
* if running on GoogleAppEngine, the `workerName` will be formed by concatenating the values of the environment variables `JETTY_WORKER_INSTANCE` and `GAE_MODULE_INSTANCE`
* if running on Google AppEngine, the `workerName` will be formed by concatenating the values of the environment variables `JETTY_WORKER_INSTANCE` and `GAE_MODULE_INSTANCE`
* otherwise, the `workerName` will be formed by concatenating the environment variable `JETTY_WORKER_INSTANCE` and the literal `0`.
So, if you're not running on Google AppEngine, and you haven't configured one, the workerName will always be: `node0`.
IMPORTANT: If you have more than one Jetty instance, it is *crucial* that you configure the `workerName` differently for each instance.
jetty.sessionScavengeInterval.seconds::
This is the period in _seconds_ between runs of the `HouseKeeper`, responsible for orchestrating the removal of expired sessions.
By default it will run every 600 secs (ie 10 mins).
As a rule of thumb, you should ensure that the scavenge interval is shorter than the `<session-timeout>` of your sessions to ensure that they are promptly scavenged.
As a rule of thumb, you should ensure that the xref:op-session-base-scavenge[scavenge] interval is shorter than the `<session-timeout>` of your sessions to ensure that they are promptly scavenged.
On the other hand, if you have a backend store configured for your sessions, xref:op-session-base-scavenge[scavenging] too frequently can increase the load on it.
TIP: Don't forget that the `<session-timeout>` is specified in web.xml in _minutes_ and the vaue of the `jetty.sessionScavengeInterval.seconds` is in _seconds_.
TIP: Don't forget that the `<session-timeout>` is specified in web.xml in _minutes_ and the value of the `jetty.sessionScavengeInterval.seconds` is in _seconds_.
[[op-session-base-scavenge]]
==== Session Scavenging
The `HouseKeeper` is responsible for the periodic initiation of session scavenge cycles.
The `jetty.sessionScavengeInterval.seconds` property in `start.d/sessions.ini` controls the periodicity of the cycle.
A session whose expiry time has been exceeded is considered eligible for scavenging.
The session can either exist in a `SessionCache` or be passivated out into the session persistence/clustering mechanism.
Scavenging occurs for all contexts on a server at every cycle.
The `HouseKeeper` sequentially asks the `SessionHandler` in each context to find and remove expired sessions.
The `SessionHandler` works with the `SessionDataStore` to evaluate candidates for expiry held in the `SessionCache`, and also to sweep the persistence mechanism to find expired sessions.
The sweep takes two forms: once per cycle the `SessionDataStore` searches for sessions for it's own context that have expired; infrequently, the `SessionDataStore` will widen the search to expired sessions in any context.
The former finds sessions that are no longer in this node's SessionCache, and using some heuristics, are unlikely to be in the `SessionCache` of another node either.
These sessions can be safely loaded and fully expired, meaning that `HttpSessionListener.destroy()` can be called for them.
The latter finds sessions that have not been disposed of by scavenge cycles on any other context/node.
As these will be sessions that expired a long time ago, and may not be appropriate to load by the context of the `SessionDataStore`, these are summarily deleted without `HttpSessionListener.destroy()` being called.
A combination of these sweeps should ensure that the persistence mechanism does not fill over time with expired sessions.
As aforementioned, the sweep period needs to be short enough to find expired sessions in a timely fashion, but not so often that it overloads the persistence mechanism.

View File

@ -16,7 +16,7 @@
// ========================================================================
//
[[op-session-filesystem]]
[[ops-session-filesystem]]
=== Persistent Sessions: File System

View File

@ -16,7 +16,7 @@
// ========================================================================
//
[[op-session-gcloud]]
[[ops-session-gcloud]]
=== Persistent Sessions: Google Cloud DataStore

View File

@ -16,7 +16,7 @@
// ========================================================================
//
[[op-session-hazelcast]]
[[ops-session-hazelcast]]
=== Persistent Sessions: Hazelcast

View File

@ -16,7 +16,7 @@
// ========================================================================
//
[[op-session-mongo]]
[[ops-session-mongo]]
=== Persistent Sessions: MongoDB

View File

@ -16,7 +16,7 @@
// ========================================================================
//
[[op-session-overview]]
[[ops-session-overview]]
=== Session Overview
@ -24,32 +24,56 @@
Before diving into the specifics of how to plug-in and configure various alternative http session management modules, let's review some useful terminology:
SessionIdManager:: A jetty instance can have a single SessionIdManager that is responsible for managing session ids.
HouseKeeper:: A jetty instance can have a single HouseKeeper that is responsible for finding and orchestrating the removal of expired sessions.
SessionCache:: A context can have a single SessionCache that is an L1 cache of in-use session objects.
SessionDataStore:: A context can have a single SessionDataStore that is responsible for all persistence operations on sessions.
CachingSessionDataStore:: A context can have a single CachingSessionDataStore that is an L2 cache of session data.
SessionHandler:: A context can have a single SessionHandler that is responsible for managing the lifecycle of sessions.
Session::
is a means of retaining information across requests for a particular user.
The Servlet Specification defines the semantics of sessions.
Some of the most important characteristics of sessions is that they have a unique id, and that their contents cannot be shared between different contexts (although the id can be).
SessionIdManager::
is responsible for allocating session ids.
Any Jetty server can have at most 1 SessionIdManager.
HouseKeeper::
is responsible for periodically orchestrating the removal of expired sessions.
This process is referred to as "scavenging".
SessionHandler::
is responsible for managing the lifecycle of sessions.
A context can have at most 1 `SessionHandler`.
SessionCache::
is an L1 cache of in-use session objects.
The `SessionCache` is used by the `SessionHandler`.
SessionDataStore::
is responsible for all clustering/persistence operations on sessions.
A `SessionCache` uses a `SessionDataStore` as a backing store.
CachingSessionDataStore::
is an L2 cache of session data.
A `SessionCache` can use a `CachingSessionDataStore` as its backing store.
More details on these concepts can be found in the [Programming Guide].
More details on these concepts can be found in the link:${PROGGUIDE}/server/sessions/sessions[Programming Guide].
[NOTE]
====
`SessionDataStores` interface with other, usually third party, systems responsible for storing and/or distributing session information.
Sessions can be distributed without being persisted.
They can also be persisted without being persisted.
Because persisting session information to a shared store is one very common way of distributing or "clustering" sessions, in the documentation we will often refer to just "persisting".
====
==== Jetty Session Modules
There are a number of modules that offer pluggable alternatives for http session management.
You can design how you want to cache and store http sessions by selecting alternative combinations of session modules.
For example, jetty ships with two alternative implementations of the `SessionCache`: one that caches sessions in memory (`session-cache-hash.mod`) and a trivial implementation that does not actually cache (`session-cache-null.mod`).
For example, jetty ships with two alternative implementations of the `SessionCache`: one that caches sessions in memory (`session-cache-hash`) and a trivial implementation that does not actually cache (`session-cache-null`).
There are at least six alternative implementations of the `SessionDataStore` that you can use to persist your http sessions.
The list current includes support for:
There are at least 6 alternative implementations of the `SessionDataStore` that you can use to persist your http sessions.
The list currently includes support for:
* file system storage (`session-store-file.mod`)
* relational database storage (`session-store-jdbc.mod`)
* NoSQL database storage (`session-store-mongo.mod`)
* Google Cloud datastore storage (`session-store-gcloud.mod`)
* Hazelcast storage (`session-store-hazelcast-remote.mod` or `session-store-hazelcast-embedded.mod`)
* Infinispan storage (`session-store-infinispan-remote.mod` or `session-store-infinispan-embedded.mod`)
* file system storage (`session-store-file`)
* relational database storage (`session-store-jdbc`)
* NoSQL database storage (`session-store-mongo`)
* Google Cloud datastore storage (`session-store-gcloud`)
* Hazelcast storage (`session-store-hazelcast-remote` or `session-store-hazelcast-embedded`)
* Infinispan storage (`session-store-infinispan-remote` or `session-store-infinispan-embedded`)
You might like to consult the [use-cases] to help you decide which combinations best suit your needs.
You might like to consult the xref:ops-session-usecases[use cases] to help you decide which combinations best suit your needs.
TIP: It is worth noting that if you do not configure _any_ session modules, jetty will still provide http sessions that are cached in memory but are never persisted.

View File

@ -16,7 +16,7 @@
// ========================================================================
//
[[op-session-sessioncache]]
[[ops-session-sessioncache]]
=== SessionCache Alternatives
In this section we will look at the alternatives for the `SessionCache`, ie the L1 cache of in-use session objects.

View File

@ -16,7 +16,7 @@
// ========================================================================
//
[[sessions-usecases]]
[[ops-session-usecases]]
=== Session Use Cases
==== Clustering with a Sticky Load Balancer
@ -59,14 +59,14 @@ As the Session is cached while at least one request is accessing it, it is possi
For various reasons it might not be possible for the `SessionDataStore` to re-read a stored session.
One scenario is that the session stores a serialized object in it's attributes, and after a redeployment there in an incompatible class change.
Using the setter `SessionCache.setRemoveUnloadableSessions(true)` will allow the `SessionDataStore` to delete the unreadable session from persistent storage.
This can be useful from preventing the scavenger from continually generating errors on the same expired, but un-restorable, session.
This can be useful for preventing the xref:ops-session-base-scavenge[scavenger] from continually generating errors on the same expired, but un-restorable session.
==== Configuring Sessions via Jetty XML
With the provided session modules, there is no need to configure a context xml or `jetty-web.xml` file for sessions.
That said, if a user wishes to configure sessions this way, it is possible using link:#jetty-xml-syntax[Jetty IoC XML format.]
That said, if a user wishes to configure sessions this way, it is possible using xref:jetty-xml-syntax[Jetty IoC XML format.]
Below is an example of how you could configure a the link:#configuring-sessions-file-system[`FileSessionDataStore`], but the same concept would apply to any of the *SessionDataStores discussed in this chapter:
Below is an example of how you could configure a the xref:ops-session-filesystem[`FileSessionDataStore`], but the same concept would apply to any of the *SessionDataStores discussed in this chapter:
[source, xml, subs="{sub-order}"]
----
@ -86,7 +86,7 @@ Below is an example of how you could configure a the link:#configuring-sessions-
</Configure>
----
The example above functions in either a `jetty-web.xml` file or a link:#using-basic-descriptor-files[context xml descriptor file.]
The example above functions in either a `jetty-web.xml` file or a xref:using-basic-descriptor-files[context xml descriptor file.]
[NOTE]
====