Session doc update.

Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
Jan Bartel 2020-09-17 15:27:04 +02:00
parent 2ae4cc8a8a
commit 21539de448
6 changed files with 161 additions and 4 deletions

View File

@ -139,7 +139,7 @@ As previously mentioned, we highly recommend that you extend the link:{JDURL}/or
===== Heterogenous Caching
Using one of the s`SessionCacheFactory``s will ensure that every time a `SessionHandler` starts it will create a new instance of the corresponding type of `SessionCache`.
Using one of the ``SessionCacheFactory``s will ensure that every time a `SessionHandler` starts it will create a new instance of the corresponding type of `SessionCache`.
But, what if you deploy multiple webapps, and for one of them, you don't want to use sessions?
Or alternatively, you don't want to use sessions, but you have one webapp that now needs them?

View File

@ -0,0 +1,88 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
[[pg-server-session-sessiondatastore-file]]
==== Session Components: The FileSessionDataStore
The `FileSessionDataStore` supports persistent storage of session data in a filesystem.
IMPORTANT: Persisting sessions to the local file system should *never* be used in a clustered environment.
One file represents one session in one context.
File names follow this pattern:
+[expiry]_[contextpath]_[virtualhost]_[id]+
expiry::
This is the expiry time in milliseconds since the epoch.
contextpath::
This is the context path with any special characters, including `/`, replaced by the `_` underscore character.
For example, a context path of `/catalog` would become `_catalog`.
A context path of simply `/` becomes just `__`.
virtualhost::
This is the first virtual host associated with the context and has the form of 4 digits separated by `.` characters.
If there are no virtual hosts associated with a context, then `0.0.0.0` is used:
[digit].[digit].[digit].[digit]
id::
This is the unique id of the session.
Putting all of the above together as an example, a session with an id of `node0ek3vx7x2y1e7pmi3z00uqj1k0` for the context with path `/test` with no virtual hosts and an expiry of `1599558193150` would have a file name of:
`1599558193150__test_0.0.0.0_node0ek3vx7x2y1e7pmi3z00uqj1k0`
==== Configuration
You can configure either a `FileSessionDataStore` individually, or a `FileSessionDataStoreFactory` if you want multiple ``SessionHandler``s to use ``FileSessionDataStore``s that are identically configured.
The configuration methods are:
storeDir::
This is a File that defines the location for storage of session files.
If the directory does not exist at startup, it will be created.
If you use the same `storeDir` for multiple `SessionHandlers`, then the sessions for all of those contexts are stored in the same directory.
This is not a problem, as the name of the file is unique because it contains the context information.
You _must_ supply a value for this, otherwise startup of the `FileSessionDataStore` will fail.
deleteUnrestorableFiles::
Boolean, default `false`.
If set to `true`, unreadable files will be deleted.
This is useful to prevent repeated logging of the same error when the xref:pg-server-session-housekeeper[scavenger] periodically (re-)attempts to load the corrupted information for a session in order to expire it.
gracePeriod::
See xref:pg-server-session-sessiondata-grace[the gracePeriod].
savePeriod::
See xref:pg-server-session-sessiondata-skip[the savePeriod].
Let's look at an example of configuring a `FileSessionDataStoreFactory`:
[source,java,indent=0]
----
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=filesessiondatastorefactory]
----
Here's an alternate example, configuring a `FileSessionDataStore` directly:
[source,java,indent=0]
----
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=filesessiondatastore]
----

View File

@ -65,6 +65,7 @@ Normally, whenever the last concurrent request leaves a `Session`, the `SessionD
If the `savePeriod` is non-zero, the `SessionData` will not be persisted if no session attributes changed, _unless_ the time since the last save exceeds the `savePeriod`.
Setting a non-zero value can reduce the load on the persistence mechanism, but in a clustered environment runs the risk that other nodes will see the session as expired because it has not been persisted sufficiently recently.
[[pg-server-session-sessiondata-grace]]
gracePeriod::
The `gracePeriod` is an interval defined in seconds.
It is an attempt to deal with the non-transactional nature of sessions with regard to finding sessions that have expired.

View File

@ -45,7 +45,7 @@ The `DefaultSessionIdManager` uses `SecureRandom` to generate unique session ids
The `SessionHandler` class, which is used by both the `ServletContextHandler` and the `WebAppContext` classes, will instantiate a `DefaultSessionIdManager` on startup if it does not detect one already present for the `Server`.
Here is an example of explicitly setting up a `DefaultSessionIdManager` in code:
Here is an example of explicitly setting up a `DefaultSessionIdManager` with a `workerName` of `server3` in code:
[source,java,indent=0]
----

View File

@ -25,4 +25,5 @@ include::session-architecture.adoc[]
include::session-sessionidmgr.adoc[]
include::session-sessioncache.adoc[]
include::session-sessiondatastore.adoc[]
include::session-sessiondatastore-file.adoc[]
include::session-cachingsessiondatastore.adoc[]

View File

@ -18,10 +18,15 @@
package org.eclipse.jetty.docs.programming.server.session;
import java.io.File;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.session.DefaultSessionCache;
import org.eclipse.jetty.server.session.DefaultSessionCacheFactory;
import org.eclipse.jetty.server.session.DefaultSessionIdManager;
import org.eclipse.jetty.server.session.FileSessionDataStore;
import org.eclipse.jetty.server.session.FileSessionDataStoreFactory;
import org.eclipse.jetty.server.session.HouseKeeper;
import org.eclipse.jetty.server.session.NullSessionCache;
import org.eclipse.jetty.server.session.NullSessionCacheFactory;
@ -37,7 +42,7 @@ public class SessionDocs
Server server = new Server();
DefaultSessionIdManager idMgr = new DefaultSessionIdManager(server);
//you must set the workerName unless you set the env viable JETTY_WORKER_NAME
idMgr.setWorkerName("3");
idMgr.setWorkerName("server3");
server.setSessionIdManager(idMgr);
//end::default[]
}
@ -49,7 +54,7 @@ public class SessionDocs
//tag::housekeeper[]
Server server = new Server();
DefaultSessionIdManager idMgr = new DefaultSessionIdManager(server);
idMgr.setWorkerName("7");
idMgr.setWorkerName("server7");
server.setSessionIdManager(idMgr);
HouseKeeper houseKeeper = new HouseKeeper();
@ -139,4 +144,66 @@ public class SessionDocs
app2.getSessionHandler().setSessionCache(nullSessionCache);
//end::mixedsessioncache[]
}
public void fileSessionDataStoreFactory()
{
//tag::filesessiondatastorefactory[]
Server server = new Server();
//First lets configure a DefaultSessionCacheFactory
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
//NEVER_EVICT
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
cacheFactory.setFlushOnResponseCommit(true);
cacheFactory.setInvalidateOnShutdown(false);
cacheFactory.setRemoveUnloadableSessions(true);
cacheFactory.setSaveOnCreate(true);
//Add the factory as a bean to the server, now whenever a
//SessionHandler starts it will consult the bean to create a new DefaultSessionCache
server.addBean(cacheFactory);
//Now, lets configure a FileSessionDataStoreFactory
FileSessionDataStoreFactory storeFactory = new FileSessionDataStoreFactory();
storeFactory.setStoreDir(new File("/tmp/sessions"));
storeFactory.setGracePeriodSec(3600);
storeFactory.setSavePeriodSec(0);
//Add the factory as a bean on the server, now whenever a
//SessionHandler starts, it will consult the bean to create a new FileSessionDataStore
//for use by the DefaultSessionCache
server.addBean(storeFactory);
//end::filesessiondatastorefactory[]
}
public void fileSessionDataStore()
{
//tag::filesessiondatastore[]
//create a context
WebAppContext app1 = new WebAppContext();
app1.setContextPath("/app1");
//First, we create a DefaultSessionCache
DefaultSessionCache cache = new DefaultSessionCache(app1.getSessionHandler());
cache.setEvictionPolicy(SessionCache.NEVER_EVICT);
cache.setFlushOnResponseCommit(true);
cache.setInvalidateOnShutdown(false);
cache.setRemoveUnloadableSessions(true);
cache.setSaveOnCreate(true);
//Now, we configure a FileSessionDataStore
FileSessionDataStore store = new FileSessionDataStore();
store.setStoreDir(new File("/tmp/sessions"));
store.setGracePeriodSec(3600);
store.setSavePeriodSec(0);
//Tell the cache to use the store
cache.setSessionDataStore(store);
//Tell the contex to use the cache/store combination
app1.getSessionHandler().setSessionCache(cache);
//end::filesessiondatastore[]
}
}