分布式中解决session共享方案

分布式中解决session共享方案

1. nginx方案

nginx提供了ip_hash策略,可以保持用户ip进行hash值计算固定分配到某台服务器上,然后只要是该ip则会保持分配到该服务器上,保证用户访问的是同一台服务器,那么session问题就不存在了。这也是解决session共享的一种方式,也称为黏性session。但是假设一台tomcat服务器挂了的话,那么session也会丢失。所以比较好的方案是抽取session。
分布式中解决session共享方案_第1张图片

2. tomcat方案

tomcat与redis集成实现session共享:
环境为tomcat7 + jdk1.6的话:
在所有需要共享session的服务器的tomcat中目录下:
lib目录中添加以下三个jar包,注意版本最好一致,不然极容易出现错误,下边的测试是可用的:
在这里插入图片描述
conf目录中content.xml中加入:配置redis服务
分布式中解决session共享方案_第2张图片
环境为tomcat7 + jdk1.7或1.8的话:
在所有需要共享session的服务器的tomcat中目录下:
lib目录中添加以下三个jar包,测试通过:
在这里插入图片描述
conf目录中content.xml中加入:配置redis服务
分布式中解决session共享方案_第3张图片
根据我这测试,是jkd1.8+tomcat7,在137和139两台tomcat中加入jar包且进行如上配置:
分布式中解决session共享方案_第4张图片
修改content.xml
分布式中解决session共享方案_第5张图片

添加两个注意点

1、按照如上配置,使用redis数据库,放入session中的对象必须要实现java.io.Serializable接口,使用memcache的可以不用实现Serializable接口
原因是:因为tomcat里使用的将session放置redis使用的工具类,是使用的jdk序列化模式存储的,这一点也是很容易理解的,session.setAttribute(String key, Object value),存储Object类型
object放入redis中又要能取出来,只能是序列化进行存储了,然后取出的时候进行反序列化。
所以我们在session中存储的任何对象,都必须实现序列化接口。
2、按照如上配置,使用redis做session存储空间时,web应用的session-time的时间单位会变成[秒],而不是原本的[分]
原因是:因为tomcat里使用的将session放置redis使用的工具类,在存储时为对tomcat容器时间做转换
在redis中设置过期时间是使用秒作为单位的,有个命令叫expire可以设置redis键值过期时间,所以在context.xml配置文件中我们需要制定session过期时间(默认是60秒,配成1800即30分钟),这一点很重要。
请注意!!!!
context.xml配置说明:
分布式中解决session共享方案_第6张图片
3.Spring Session+Spring Data Redis 解决
(1)引入相关jar包:
这里需要引入Spring Session和Spring Data Redis相关的依赖jar包。可以自行从maven仓库下载,也可以参考使用的jar包:down.51cto.com/data/228183…
(2)修改spring-data-redis相关配置:
在项目的spring-data-redis相关配置中添加以下配置:




完整的context_redis_cluster.xml文件如下:


spring-data-redis-cluster



    
    
    
        
            
                
                
            
            
                
                
            
            
                
                
            
            
                
                
            
            
                
                
            
            
                
                
            
        
    



    
    
    
    



    
    
    






    
    
    
    
    





    
    

注:对应的属性文件是: #Redis Cluster redis.cluster.maxRedirects=3

redis.cluster.host1=192.168.1.30
redis.cluster.port1=7000

redis.cluster.host2=192.168.1.30
redis.cluster.port2=7001

redis.cluster.host3=192.168.1.30
redis.cluster.port3=7002

redis.cluster.host4=192.168.1.224
redis.cluster.port4=7003

redis.cluster.host5=192.168.1.224
redis.cluster.port5=7004

redis.cluster.host6=192.168.1.224
redis.cluster.port6=7005

#JedisPoolConfig
redis.cluster.jedisPoolConfig.maxTotal=1024
redis.cluster.jedisPoolConfig.maxIdle=20
redis.cluster.jedisPoolConfig.maxWaitMillis=100000
redis.cluster.jedisPoolConfig.testOnBorrow=true

#JedisConnectionFactory
redis.cluster.jedisConnectionFactory.password=admin
(3)修改web.xml:
在web.xml中添加以下filter:


springSessionRepositoryFilter
org.springframework.web.filter.DelegatingFilterProxy


springSessionRepositoryFilter
/*

注:需要将这个filter放在第一位,其他的如编码、shiro等filter需要放在这之后
到此,Spring Session和Spring Data Redis就整合到项目中了
(4)测试:
运行项目后,可以发现生成了一个名为“SESSION”的cookie。接着在我们登录之后,可以通过其cookie值在redis上取得保存的对应的session对象。如下图所示:
分布式中解决session共享方案_第7张图片

你可能感兴趣的:(SESSION)