312 lines
15 KiB
Plaintext
312 lines
15 KiB
Plaintext
[[geode-samples-caching-http-session]]
|
|
= HTTP Session State Caching with Spring
|
|
:apache-geode-version: {apache-geode-doc-version}
|
|
:apache-geode-name: Apache Geode
|
|
:apache-geode-docs: https://geode.apache.org/docs/guide/{apache-geode-version}
|
|
:apache-geode-javadoc: https://geode.apache.org/releases/latest/javadoc
|
|
:apache-geode-website: https://geode.apache.org/
|
|
:images-dir: ./images
|
|
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/html
|
|
:spring-boot-javadoc: https://docs.spring.io/spring-boot/docs/current/api
|
|
:spring-data-geode-docs: https://docs.spring.io/spring-data/geode/docs/current/reference/html
|
|
:spring-data-geode-javadoc: https://docs.spring.io/spring-data/geode/docs/current/api
|
|
:spring-framework-docs: https://docs.spring.io/spring/docs/current/spring-framework-reference
|
|
:spring-framework-javadoc: https://docs.spring.io/spring/docs/current/javadoc-api
|
|
:spring-session-docs: https://docs.spring.io/spring-session/docs/current/reference/html5
|
|
:spring-session-javadoc: https://docs.spring.io/spring-session/docs/current/api
|
|
:spring-session-website: https://spring.io/projects/spring-session
|
|
:toc: left
|
|
:toclevels: 2
|
|
:stylesdir: ../
|
|
:highlightjsdir: ../js/highlight
|
|
:docinfodir: guides
|
|
|
|
|
|
This guide walks you through building a simple Spring Boot application using {spring-session-website}[Spring Session]
|
|
backed by {apache-geode-website}[{apache-geode-name}] to manage HTTP Session state.
|
|
|
|
It is assumed that the reader is familiar with the Spring _programming model_ as well as the _Java Servlet_ API.
|
|
No prior knowledge of Spring Session or {apache-geode-name} is required to utilize HTTP Session State Caching in your
|
|
Spring Boot applications.
|
|
|
|
Let's begin.
|
|
|
|
TIP: Refer to the link:../index.html#geode-session[Spring Session] chapter in the reference documentation
|
|
for more information.
|
|
|
|
[#index-link]
|
|
link:../index.html[Index]
|
|
|
|
link:../index.html#geode-samples[Back to Samples]
|
|
|
|
[[geode-samples-caching-http-session-background]]
|
|
== Background
|
|
|
|
HTTP Session Caching is one of the most used forms of caching in enterprise applications, especially given
|
|
the proliferation of Web applications in the enterprise.
|
|
|
|
HTTP Sessions are primarily used to manage conversational state with users of your Web applications between HTTP
|
|
requests given that HTTP is a stateless protocol. This is due to the fact that HTTP connections are not persistent.
|
|
When an HTTP client makes a request, the client opens a connection to the server, sends an HTTP request, waits for
|
|
the server to process the request and respond, and then closes the connection. Each time an HTTP request is sent,
|
|
the same procedure is followed.
|
|
|
|
Of course, there are alternatives to HTTP when making remote Web Service requests. For instance, if you are using
|
|
https://en.wikipedia.org/wiki/WebSocket[WebSockets] in your applications, then you would have persistent connections
|
|
and would most likely be using either the https://stomp.github.io/[STOMP] or https://wamp-proto.org/[WAMP] protocols.
|
|
|
|
TIP: The core Spring Framework has {spring-framework-docs}/web.html#websocket[first-class support] for _WebSockets_
|
|
over the STOMP protocol.
|
|
|
|
TIP: Spring Session additionally {spring-session-docs}/#websocket[supports] Session State Management for _WebSockets_.
|
|
|
|
As mentioned above, it is useful to use the HTTP Session to manage conversational state with users of your applications
|
|
so that they can experience continuity between separate interactions (i.e. HTTP requests). In order to maintain that
|
|
continuity and provide a consistent, uninterrupted experience, the HTTP Session must be preserved in a reliable manner.
|
|
|
|
One way to do this is to employ a data management solution in your application architecture that 1) makes the HTTP
|
|
Session highly available and 2) makes the HTTP Session resilient to failures in the system architecture.
|
|
|
|
{apache-geode-name} is ideal for managing HTTP Session state given that it can distribute data/state across a scaled-out,
|
|
highly-available architecture by replicating data in a redundant and organized (partitioned) manner, thereby making
|
|
the data resilient to network and hardware failures.
|
|
|
|
This is ideal in a cloud environment given that you will most likely be running multiple instances of your application
|
|
in order to serve the demand, especially during peak loads. In these cases, you will undoubtedly face failures and each
|
|
application instance will need to be prepared to take over in a moments notice to provide the consistent, uninterrupted
|
|
experience to which we alluded to above. These applications instances will need access to the same HTTP Session state.
|
|
|
|
An application architecture with HTTP Session State Caching appears as follows:
|
|
|
|
image::{images-dir}/HTTP-Session-Caching.png[]
|
|
|
|
Essentially, anytime an HTTP Session is requested by your Spring Boot, Web Application, the Servlet Container
|
|
(e.g. Apache Tomcat) delegates to Spring Session to provide the implementation of `javax.servlet.http.HttpSession`.
|
|
After all, `javax.servlet.http.HttpServlet` is an interface that can have many implementations.
|
|
|
|
Effectively, Spring Session provides it's own implementation of the `javax.servlet.http.HttpSession` interface through
|
|
a Servlet `Filter` that gets registered by Spring Session programmatically when Spring Session is on the application
|
|
classpath.
|
|
|
|
Spring Session's implementation of the `javax.servlet.http.HttpSession` interface can backed by many different providers
|
|
that implement the Spring Session framework's `SessionRepository` interface.
|
|
|
|
Spring Session's architecture can be depicted as follows:
|
|
|
|
image::{images-dir}/Spring-Session-Framework-Architecture.png[]
|
|
|
|
Again, the `SessionRepository` interface is the central component of the framework enabling any backend data store
|
|
to be adapted and serve as a provider for managing the HTTP Sessions.
|
|
|
|
This is effectively how https://github.com/spring-projects/spring-session-data-geode[Spring Session for {apache-geode-name}]
|
|
works.
|
|
|
|
[[geode-samples-caching-http-session-example]]
|
|
== Example
|
|
|
|
For our example, we are going to keep the Web application relatively simple. Essentially, we just want to show you
|
|
how easy it is to use Spring Session in your Spring Boot, Web applications, to manage the HTTP Session state.
|
|
|
|
So, we are going to switch from Servlet Container (e.g. Apache Tomcat) to Spring Session managed HTTP Sessions with a
|
|
single-line configuration change.
|
|
|
|
First, let's introduce the Spring Web MVC `Controller` in our Spring Boot, Web application.
|
|
|
|
[[geode-samples-caching-http-session-example-controller]]
|
|
=== Controller
|
|
|
|
Our Spring Web MVC `Controller` class is implemented as follows:
|
|
|
|
.Spring Boot, Web Application Controller
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/caching/http-session/src/main/java/example/app/caching/session/http/controller/CounterController.java[tags=class]
|
|
----
|
|
|
|
The main Web Service endpoint in our Spring Boot, Web application is the `/session` endpoint, which is accessible from
|
|
http//:localhost:8080/session[].
|
|
|
|
The `/session` endpoint outputs 3 bits of information:
|
|
|
|
1. The `javax.servlet.http.HttpSession` class type.
|
|
2. Current HTTP Session count.
|
|
3. Current HTTP Request count.
|
|
|
|
The `HttpSession` class type lets us know which implementation (e.g. Servlet Container vs. Spring Session) is being used
|
|
to manage the HTTP Session state.
|
|
|
|
The HTTP Request count is simply incremented every time a client HTTP Request is made to the HTTP server (e.g. Servlet
|
|
Container) before the HTTP Session expires. If the HTTP Session expires before another client HTTP Request is made,
|
|
then the HTTP Session count is incremented and the HTTP Request count resets to 1.
|
|
|
|
[[geode-samples-caching-http-session-example-configuration]]
|
|
=== Configuration
|
|
|
|
.Spring Boot, Web Application Configuration
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/caching/http-session/src/main/resources/application.properties[]
|
|
----
|
|
|
|
The configuration is quite simple. In this case, we have set the HTTP Session `timeout`, using the
|
|
`server.servlet.session.timeout` property, to *15 seconds*. This property is used to configure the HTTP Session timeout
|
|
regardless of whether the HTTP Session is being managed by the Servlet Container or by Spring Session.
|
|
|
|
Though not strictly necessary, we configured name for the Pool of connections used by Spring Session Data Geode in case
|
|
the application is switched to a client/server topology to the "_DEFAULT_" Pool. We also explicitly named the Region
|
|
used to store HTTP Session state as "_Sessions_" (default name is "_ClusteredSpringSessions_").
|
|
|
|
TIP: In most production deployments, you will likely be using a client/server topology, where the HTTP Session is
|
|
managed by a cluster of {apache-geode-name} servers so that the HTTP Session can be shared across multiple instances
|
|
of the Spring Boot, Web application. This would be especially true in a cloud environment when utilizing a Microservices
|
|
architecture. However, for example purposes, we tried to keep the sample as simple as possible.
|
|
|
|
NOTE: The default data management policy for the client cache (a.k.a. Region) used to manage HTTP Session state is a
|
|
`PROXY`, which is the basis for the client/server topology. Therefore, the default configuration assumes you will be
|
|
using the client/server topology in most of your applications.
|
|
|
|
The main Spring Boot application class is not particularly interesting other than we have annotated the class with the
|
|
`@EnableClusterAware` annotation to seamlessly switch between a client local context and a client/server topology:
|
|
|
|
.Spring Boot, Web Application Configuration
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/caching/http-session/src/main/java/example/app/caching/session/http/BootGeodeHttpSessionCachingApplication.java[]
|
|
----
|
|
|
|
Refer to SBDG's documentation to learn about the
|
|
link:../index.html#geode-configuration-declarative-annotations-productivity-enableclusteraware[`@EnableClusterAware`]
|
|
annotation.
|
|
|
|
[[geode-samples-caching-http-session-example-classpath]]
|
|
=== Classpath
|
|
|
|
The only essential components of the application classpath is a compile-time dependency on `spring-boot-starter-web`:
|
|
|
|
.`spring-boot-starter-web` compile-time dependency declaration
|
|
[source,xml]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
Along with a runtime dependency on `spring-boot-starter-tomcat`. You may choose to use another Servlet Container,
|
|
such as Eclipse Jetty by declaring the `spring-boot-starter-jetty` runtime dependency.
|
|
|
|
.`spring-boot-starter-tomcat` runtime dependency declaration
|
|
[source,xml]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
|
</dependency>
|
|
----
|
|
|
|
Spring Boot will detect Apache Tomcat on the application classpath and bootstrap an embedded, Apache Tomcat Servlet
|
|
Container using a derived `WebApplicationContext`.
|
|
|
|
[[geode-samples-caching-http-session-example-run]]
|
|
== Run the Example
|
|
|
|
Now its time to run the example.
|
|
|
|
You can run the `BootGeodeHttpSessionCachingApplication` class in your IDE (e.g. IntelliJ IDEA). Simply create a run
|
|
profile configuration and run it. No additional JVM arguments, System Properties or program arguments are required.
|
|
|
|
Alternatively, you can run the `BootGeodeHttpSessionCachingApplication` class from the command-line with the `gradlew`
|
|
command as follows:
|
|
|
|
.Run the example with `gradlew`
|
|
[source,text]
|
|
----
|
|
$ gradlew :spring-geode-samples-caching-httpsession:bootRun
|
|
----
|
|
|
|
[[geode-samples-caching-http-session-example-tomcat]]
|
|
== Run the Example with Apache Tomcat
|
|
|
|
After the application starts, open your Web browser to http://localhost:8080[]
|
|
|
|
image::{images-dir}/HttpSessionCachingApplication.png[]
|
|
|
|
When we navigate to the `/session` Web service endpoint:
|
|
|
|
image::{images-dir}/HttpSessionCachingApplication-ServletContainerSession.png[]
|
|
|
|
We see that the Servlet Container's implementing class for the `javax.servlet.http.HttpSession` interface is
|
|
`org.apache.catalina.session.StandardSession`.
|
|
|
|
If we continue to hit refresh in the Web browser, thereby causing additional client HTTP requests to be made to
|
|
the HTTP server, then our HTTP Request count increments. If we wait for 15 seconds, then the HTTP Session will expire,
|
|
and we will see the HTTP Session count increment along with the HTTP Request count reset to 1:
|
|
|
|
image::{images-dir}/HttpSessionCachingApplication-ServletContainerSessionExpiration.png[]
|
|
|
|
Now, we can repeat this same exercise, but this time, using Spring Session.
|
|
|
|
[[geode-samples-caching-http-session-example-run-spring-session]]
|
|
=== Run the Example with Spring Session
|
|
|
|
First, we must add Spring Session to the application's classpath. We do this simply by adding the
|
|
`spring-geode-starter-session` runtime dependency to the classpath of our example application:
|
|
|
|
.`spring-geode-starter-session` runtime dependency declaration
|
|
[source,xml]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.geode</groupId>
|
|
<artifactId>spring-geode-starter-session</artifactId>
|
|
<scope>runtime</scope>
|
|
</dependency>
|
|
----
|
|
|
|
The `spring-geode-starter-session` dependency adds Spring Session to the application's classpath at runtime
|
|
and positions {apache-geode-name} as the provider used to manage the HTTP Session state.
|
|
|
|
With {apache-geode-name}, we gain all the benefits of using a highly concurrent, highly distributed data management solution
|
|
that provides high availability (HA) and resiliency in a cloud environment.
|
|
|
|
That's it! This is all we have to do to replace the Servlet's Container's HTTP Session management facilities with a
|
|
robust, highly available, highly resilient, clustered solution provided by Spring Session.
|
|
|
|
When we run the example again, and access the `/session` Web service endpoint, we will see:
|
|
|
|
image::{images-dir}/HttpSessionCachingApplication-SpringSession.png[]
|
|
|
|
Now we see that the implementing class for the `javax.servlet.http.HttpSession` is
|
|
`org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper`.
|
|
|
|
Easy!
|
|
|
|
Of course, the ability to scale-out and optimize the data management policies for HTTP Session management is very
|
|
provider-specific (e.g. {apache-geode-name}) and highly dependent on the use case as well a application requirements,
|
|
therefore is beyond the scope of this guide.
|
|
|
|
[[geode-samples-caching-http-session-summary]]
|
|
== Summary
|
|
|
|
Spring Session is a powerful framework for managing your HTTP Session state. Not only does it allow you to plugin
|
|
different backend data management providers (as of this writing):
|
|
|
|
* https://github.com/spring-projects/spring-session-data-geode#spring-session-for-apache-geode--pivotal-gemfire[_{apache-geode-name}_]
|
|
* {spring-session-website}[_Hazelast_]
|
|
* {spring-session-website}[_JDBC_]
|
|
* https://spring.io/projects/spring-session-data-mongodb[_MongoDB_]
|
|
* {spring-session-website}[_Redis_]
|
|
|
|
Spring Session also allows you to manage different types of Sessions depending on the context:
|
|
|
|
* {spring-session-docs}/#httpsession[_HttpSession_]
|
|
* {spring-session-docs}/#websocket[_WebSocket_]
|
|
* {spring-session-docs}#websession[_WebSession_ (Reactive)]
|
|
|
|
Therefore, it makes it a simple matter to switch providers, or adopt additional Session management capabilities as your
|
|
application requirements change and/or your use cases grow.
|
|
|
|
HTTP Session state caching is one of the most effective and common ways to utilize caching in your Spring Boot,
|
|
Web applications, and ensure the users experience is first-class.
|
|
|
|
link:../index.html#geode-samples[Back to Samples]
|