分布式session

session介绍

当访问服务器某个网页的时候,会在服务器端的内存里开辟一块内存,这块内存就叫做session,而这个内存是跟浏览器关联在一起的。这个浏览器指的是浏览器窗口,或者是浏览器的子窗口,意思就是,只允许当前这个session对应的浏览器访问,就算是在同一个机器上新启的浏览器也是无法访问的。而另外一个浏览器也需要记录session的话,就会再启一个属于自己的session.session主要是将数据存放在服务器端。

分布式session

而在分布式系统中session的使用面临两大问题。
一:session只会讲客户端的信息存放在本服务器中,而在分布式系统中,可能一个服务会存放在多个服务器中,就会造成当用户第一次访问时,将自己的session存放在一号服务器,第二次访问是,会被gateway路由到其它服务器上,其它服务器就不会存在用户存在一号服务器上的session。
解决办法:session复制、客户端存储、hash一致性(通过更改负载均衡,使得该客户端的每次请求,都会访问同一个服务器)、统一存储(使用第三方存储,如:redis)
详细介绍统一存储: session会存放在服务器端,但我们可以通过服务器将其存放在第三方的存储系统中,redis。客户端每次访问时,我们就可以直接去redis中取数据,redis中还可以设置过期时间,可以水平扩展服务器,服务器重启并不会影响session。
不足之处:增加了一次网络调用,比较依赖第三方服务。
二:子域session共享问题,上诉中的统一存储,必须是在同一个域名下,因为服务器端会将session的信息存放到浏览器端的cookies中,但是针对不同的域名,session的数据作用范围是仅局限于当前域名下的。
servletResponse.addCookies(new Cookies("key",value).setDomain(""))//默认的Tomcat是设置的是在本域名下
所以为了解决此问题,我们可以使用springsession来解决此问题,将session的作用域进行放大,放大到与父域名同级,就可以让子域来获取session了。

使用springsession

第一步:导入依赖

springsession的依赖
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
    <version>2.3.0.RELEASE</version>
</dependency>

第二步:配置配置文件

spring.session.store-type=redis 指定是用redis
//server.servlet.session.timeout=  设置超时时间
//spring.session.redis.flush-mode=on_save 刷新方式
//spring.session.redis.namespace=spring:session # Namespace for keys used to store sessions.
//因为是整合redis所以还需要配置redis
spring.redis.host=localhost 主机
spring.redis.password= 密码
spring.redis.port=6379 端口默认是6379

第三步:对springsession进行配置

@EnableRedisHttpSession 
public class Config {

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

}

以上要存储的数据需实现Java的序列化,并将数据以Java序列化的形式存放在redis中,这样不容易观察和取值,所以我们需要自定义序列化的方式,以json的样式保存在redis中。

@Bean
	public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
		return new GenericJackson2JsonRedisSerializer();
	}

我们需要设置cookie的作用域是父域名

@Bean
	public CookieSerializer cookieSerializer() {
		DefaultCookieSerializer serializer = new DefaultCookieSerializer();
		serializer.setCookieName("JSESSIONID"); //cookie的key
		serializer.setCookiePath("/"); 
		serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$"); //设置为父域名
		return serializer;
	}

总结 经过以上步骤,就可以实现分布式session了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值