零配置文件利用spring-session实现集群session共享

普通单服务器web应用中,Session都是由容器管理,存放到内存中。如果搭建分布式集群,就需要保证

各个服务器中所使用的Session一致。比较简单的方式就是设计一个Filter,利用HttpServletRequestWrapper,

直接将Session换成自己管理。这也就是spring-session的设计思路。

1、介绍

    GitHub地址:https://github.com/spring-projects/spring-session

2、简单实例

   1)增加依赖jar

<dependency>
	    <groupId>org.springframework.data</groupId>
	    <artifactId>spring-data-redis</artifactId>
	    <version>1.4.2.RELEASE</version>
	 </dependency>
	<dependency>
	    <groupId>redis.clients</groupId>
	    <artifactId>jedis</artifactId>
	    <version>2.5.2</version>
	</dependency>
	<!-- Spring Session -->
	<dependency>
	       <groupId>org.springframework.session</groupId>
	       <artifactId>spring-session-data-redis</artifactId>
           <version>1.2.0.RELEASE</version>
           <type>pom</type>
	</dependency>
	<dependency>
	      <groupId>org.apache.commons</groupId>
	      <artifactId>commons-pool2</artifactId>
	      <version>2.2</version>
	</dependency>
	<dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${springframework.version}</version>
        </dependency>
      <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>   
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>  
			<groupId>org.springframework</groupId>  
			<artifactId>spring-aop</artifactId>  
			<version>${springframework.version}</version>  
	    </dependency>       
     <dependency>
       <groupId>javax.servlet</groupId>
	    <artifactId>javax.servlet-api</artifactId>
	    <version>3.1.0</version>
	    <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency> 

   2)编写一个配置类,用来启用RedisHttpSession功能,并向Spring容器中注册一个RedisConnectionFactory,并增加session监听器

@EnableRedisHttpSession(maxInactiveIntervalInSeconds=3000) 
public class Config {

        @Bean
        public JedisConnectionFactory connectionFactory() {
            RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration() .master("mymaster")
                    .sentinel("192.168.191.11", 26379).sentinel("192.168.191.11", 26479).sentinel("192.168.191.11", 26579);
            JedisConnectionFactory jcf = new JedisConnectionFactory(sentinelConfig);
            jcf.setPassword("123456");
                    return jcf;
        }
        /**
         * 自定义session监听器
         * @return
         */
        @Bean
        public ApplicationListener sessionListener(){
            return new SessionListener();
        }
}

由于不再使用web容器所管理的session,原有通过web.xml中增加配置设置session时效,及session监听的方式也不再适用。可使用maxInactiveIntervalInSeconds来设置session失效时间,单位(秒)。

 3)由于spring-session将session的事件注册到ApplicationEvent中,可以使用自定监听器用来监听

public class SessionListener implements ApplicationListener<AbstractSessionEvent> {

    @Override
    public void onApplicationEvent(AbstractSessionEvent event) {
        if (event instanceof SessionCreatedEvent) {  
            System.out.println("创建session");  
        }
        if (event instanceof SessionDestroyedEvent) {  
            System.out.println("销毁session");  
        }
    }

}

 4)将RedisHttpSessionConfig及监听器加入spring容器中

public class Initializer extends AbstractHttpSessionApplicationInitializer {
    public Initializer() {
        super(Config.class); 
    }
}

 5)测试servlet

@WebServlet("/session")
public class SessionServlet extends HttpServlet {

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                        throws ServletException, IOException {
                req.getSession().setAttribute("A", "test");
                resp.sendRedirect(req.getContextPath() + "/");
        }

        private static final long serialVersionUID = 2878267318695777395L;
}

 

  启动工程,访问servlet地址。

  Http Session数据在Redis中是以Hash结构存储的。

127.0.0.1:6379> keys *
1) "spring:session:expirations:1431577740000"
2) "spring:session:sessions:e2cef3ae-c8ea-4346-ba6b-9b3b26eee578"

     可以看到,还有一个key="spring:session:expirations:1431577740000"的数据,是以Set结构保存的。这个值记录了所有session数据应该被删除的时间(即最新的一个session数据过期的时间)。

6)需要注意的就是redis需要2.8以上版本,然后开启事件通知,在redis配置文件里面加上

notify-keyspace-events Ex

猜你喜欢

转载自beichen35.iteye.com/blog/2308530
今日推荐