Externalizing Session State for a Spring Boot Application Using Spring-Session
Externalizing Session State for a Spring Boot Application Using Spring-Session
九州暮云 发表于1年前
Externalizing Session State for a Spring Boot Application Using Spring-Session
  • 发表于 1年前
  • 阅读 43
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】如何购买服务器最划算?>>>   

摘要: Spring-session is a very cool new project that aims to provide a simpler way of managing sessions in Java based web applications.To test spring-session I have used a shopping cart type application

Spring-session is a very cool new project that aims to provide a simpler way of managing sessions in Java based web applications. One of the features that I explored with spring-session recently was the way it supports externalizing session state without needing to fiddle with the internals of specific web containers like Tomcat or Jetty.

To test spring-session I have used a shopping cart type application(available here) which makes heavy use of session by keeping the items added to the cart as a session attribute, as can be seen from these screenshots:

输入图片说明

输入图片说明

Consider first a scenario without Spring session. So this is how I have exposed my application:

输入图片说明

I am using nginx to load balance across two instances of this application. This set-up is very easy to run using Spring boot, I brought up two instances of the app up using two different server ports, this way:

mvn spring-boot:run -Dserver.port=8080
mvn spring-boot:run -Dserver.port=8082

and this is my nginx.conf to load balance across these two instances:

events {
    worker_connections  1024;
}
http {
    upstream sessionApp {
        server localhost:8080;
        server localhost:8082;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://sessionApp;
        }       
    }
}

I display the port number of the application in the footer just to show which instance is handling the request.

If I were to do nothing to move the state of the session out the application then the behavior of the application would be erratic as the session established on one instance of the application would not be recognized by the other instance - specifically if Tomcat receives a session id it does not recognize then the behavior is to create a new session.

Introducing Spring session into the application

There are container specific ways to introduce a external session stores - One example is here, where Redis is configured as a store for Tomcat. Pivotal Gemfire provides a module to externalize Tomcat's session state.

The advantage of using Spring-session is that there is no dependence on the container at all - maintaining session state becomes an application concern. The instructions on configuring an application to use Spring session is detailed very well at the Spring-session site, just to quickly summarize how I have configured my Spring Boot application, these are first the dependencies that I have pulled in:

<dependency>
 <groupId>org.springframework.session</groupId>
 <artifactId>spring-session</artifactId>
 <version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
 <groupId>org.springframework.session</groupId>
 <artifactId>spring-session-data-redis</artifactId>
 <version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
 <groupId>org.springframework.data</groupId>
 <artifactId>spring-data-redis</artifactId>
 <version>1.4.1.RELEASE</version>
</dependency>
<dependency>
 <groupId>redis.clients</groupId>
 <artifactId>jedis</artifactId>
 <version>2.4.1</version>
</dependency>

and my configuration to use Spring-session for session support, note the Spring Boot specific FilterRegistrationBean which is used to register the session repository filter:

import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.web.filter.DelegatingFilterProxy;

import java.util.Arrays;

@Configuration
@EnableRedisHttpSession
public class SessionRepositoryConfig {

 @Bean
 @Order(value = 0)
 public FilterRegistrationBean sessionRepositoryFilterRegistration(SessionRepositoryFilter springSessionRepositoryFilter) {
  FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
  filterRegistrationBean.setFilter(new DelegatingFilterProxy(springSessionRepositoryFilter));
  filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
  return filterRegistrationBean;
 }

 @Bean
 public JedisConnectionFactory connectionFactory() {
  return new JedisConnectionFactory();
 }
}

And that is it! magically now all session is handled by Spring-session, and neatly externalized to Redis.

If I were to retry my previous configuration of using nginx to load balance two different Spring-Boot applications using the common Redis store, the application just works irrespective of the instance handling the request. I look forward to further enhancements to this excellent new project.

The sample application which makes use of Spring-session is available here: https://github.com/bijukunjummen/shopping-cart-cf-app.git。

Reference:

标签: spring-session
共有 人打赏支持
粉丝 46
博文 123
码字总数 62582
×
九州暮云
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: