0

We are using Spring Session management with GemFire for Session handling. We are doing it for container deployment where one complete transaction will be processed by multiple containers. But when we are doing multiple transactions simultaneously there are random situations were the same session id is used for different transactions.

Is there any server-specific cache mechanism inside Spring Session which can cause this issue?

We can't rely on server since we use a non-sticky session approach

GemFire version being used is 2.1.2 release. The session object is using delta serialization and the objects inside the session is using PDX serialization.

Any help you can provide is appreciated.

John Blum
  • 7,381
  • 1
  • 20
  • 30
Sreejith
  • 33
  • 3
  • The (HTTP) `Session` is not "cached" across requests, or containers, by _Spring Session_ (nor _Spring Session Data GemFire_, in particular, for that matter). A `Session` is cached in the HTTP request (i.e. `HttpServletRequest`) for the duration of the HTTP request, which is useful, for example, in `forwards`. But, for each subsequent request, the `Session` is looked up by it's `Session` `ID`, which is stored in a `Cookie` set on the client-side (i.e. browser). Storing and looking up the `Session` `ID` in a `Cookie` is also _Spring Session's_ default `Session` resolution strategy. – John Blum Feb 02 '19 at 03:09
  • Additionally, it is not GemFire version `2.1.2` you are using. `2.1.2` would actually correspond to the _**Spring Session for Pivotal GemFire**_ version, `2.1.2.RELEASE` (https://search.maven.org/artifact/org.springframework.session/spring-session-data-gemfire/2.1.2.RELEASE/jar), which indirectly pulls in Pivotal GemFire 9.5.2. See here (https://github.com/spring-projects/spring-session-data-geode/blob/2.1.2.RELEASE/gradle.properties#L13) then here (https://github.com/spring-projects/spring-data-gemfire/blob/2.1.3.RELEASE/pom.xml#L25)). – John Blum Feb 02 '19 at 03:16
  • Note, this is specifically where _Spring Session_ **core** (**not** _Spring Session Data GemFire_, specifically) is storing the "current" (HTTP) `Session` in the HTTP request (i.e. `HttpServletRequest`):https://github.com/spring-projects/spring-session/blob/2.1.3.RELEASE/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L260. – John Blum Feb 02 '19 at 03:23
  • The `HttpServletRequest` is being "wrapped" by _Spring Session_ ()https://github.com/spring-projects/spring-session/blob/2.1.3.RELEASE/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L201-L202), compliments of the `SessionRepositoryFilter` (containing class). This is all initiated/driven from the overridden `getSession(:boolean)` method (https://github.com/spring-projects/spring-session/blob/2.1.3.RELEASE/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L301). – John Blum Feb 02 '19 at 03:28
  • You can even see the initial lookup here, first on "forwarded" requests, https://github.com/spring-projects/spring-session/blob/2.1.3.RELEASE/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L302, then by `Session` `ID`, by inspecting the `Cookie`, https://github.com/spring-projects/spring-session/blob/2.1.3.RELEASE/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L306. – John Blum Feb 02 '19 at 03:31
  • Actual logic here: https://github.com/spring-projects/spring-session/blob/2.1.3.RELEASE/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L373-L374. Note, the `HttpSessionIdResolver` defaults to inspecting the `Cookie` (https://github.com/spring-projects/spring-session/blob/2.1.3.RELEASE/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L111). – John Blum Feb 02 '19 at 03:32
  • Are you certain your application is not doing something funky in the way that it sends HTTP requests referencing the `Session` containing the information to be processed in a transaction, apparently concurrently, since you say simultaneously , such as when using AJAX? I would start by looking client-side, making sure the correct `Session` is identified and requested for the transaction spanning multiple containers before it is processed. I would also make sure the Servlet/Controllers don't contain any special state that must be protected, especially in a concurrent context, etc. – John Blum Feb 02 '19 at 03:43
  • Also, if you could provide a small example/test reproducing your problem, that would help greatly. Thanks! – John Blum Feb 02 '19 at 03:45
  • Thanks @JohnBlum for the comments. We will analyze more in the application side – Sreejith Feb 04 '19 at 13:40
  • @JohnBlum I had added the spring session core and spring session data geode jars as module in my project just to under how the session id is created and shared. In the SessionRepositoryFilter.getSession(boolean create) method i had added logs. Please correct me if i am wrong, when the first request is coming to server side. The server will allocate a new session Id in the response and its carried over in subsequent requests in that transaction. Is there any way that we can see the initial session ID coming from client or is it null in the first request. – Sreejith Feb 13 '19 at 12:54
  • As mentioned above, the client will send the Session ID in a Cookie (the default strategy used by _Spring Session_). If there is no "current" Session present in the HTTP request, here (https://github.com/spring-projects/spring-session/blob/master/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L302), which there won't be if this is not a forward, but a new request. Otherwise, the Session is looked up from the Cookie in the request... – John Blum Feb 13 '19 at 17:06
  • ... here (https://github.com/spring-projects/spring-session/blob/master/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L306), and specifically, here (https://github.com/spring-projects/spring-session/blob/master/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L373). The `HttpSessionIdResolver`, by default, is an instance of `CookieHttpSessionIdResolver`... – John Blum Feb 13 '19 at 17:08
  • ... here (https://github.com/spring-projects/spring-session/blob/master/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java#L111). – John Blum Feb 13 '19 at 17:08
  • @JohnBlum I was referring to the below link of managing a cache https://gemfire.docs.pivotal.io/97/geode/basic_config/the_cache/managing_a_secure_cache.html Based on that a cache must be closed after use. Since i am using spring session management. Could you please tell us how the cache is closed after use. In application many transactions will be running in parallel. At what point the cache is closed. – Sreejith Feb 19 '19 at 06:28
  • When the application is stopped. With GemFire/Geode, you don't want to open and close the cache for each request. And it would only be the `ClientCache` that is stopped in a client/server topology. The peer `Cache` distributed across the cluster on the server-side would not be stopped, and rarely, if ever should be stopped, barring upgrades, infrastructure changes, etc. – John Blum Jul 17 '19 at 22:12

0 Answers0