分布式Session与单点登录

一、分布式Session

单体项目中我们使用Session和Cookie保存用户信息,而在分布式系统中单独使用Session和Cookie无法已无法满足要求。一、Session不能跨系统保存,二、Cookie的跨域问题

1.1 分布式Session解决方案

① session 复制
在这里插入图片描述
优点:web-server (Tomcat)原生支持,只需要修改配置文件

缺点:

  • session同步需要数据传输,占用大量网络带宽,降低了服务器群的业务处理能力
  • 任意一台web-server保存的数据都是所有web-serversession总和,受到内存限制无法水平扩展更多的web-server
  • 大型分布式集群情况下,由于所有web-server都全量保存数据,所以此方案不可取。

② session 存储在客户端
在这里插入图片描述
优点:服务器不需存储session,用户保存自己的session信息到cookie中,节省服务端资源

缺点:

  • 每次http请求,携带用户在cookie中的完整信息,浪费网络带宽
  • session数据放在cookie中,cookie有长度限制4K,不能保存大量信息
  • session数据放在cookie中,存在泄漏、篡改、窃取等安全隐患

session 存储在客户端这种方式不可取,不能使用。

③ hash 一致性
在这里插入图片描述
优点:

  • 只需要改nginx配置,不需要修改应用代码
  • 负载均衡,只要hash属性的值分布是均匀的,多台web-server的负载是均衡的
  • 可以支持web-server水平扩展(session同步法是不行的,受内存限制)

缺点:

  • session还是存在web-server中的,所以web-server重启可能导致部分session丢失,影响业务,如部分用户需要重新登录
  • 如果web-server水平扩展,rehashsession重新分布,也会有一部分用户路由不到正确的session

④ 统一存储
在这里插入图片描述
优点:

  • 没有安全隐患
  • 可以水平扩展,数据库/缓存水平切分即可
  • web-server重启或者扩容都不会有session丢失

缺点:增加了一次网络调用,并且需要修改应用代码;如将所有的getSession方法替换为从Redis查数据的方式,redis获取数据比内存慢很多。

2.2 SpringSession

通常我们会选择统一存储的方案,其缺点可以使用SpringSession进行解决。

① 引入依赖

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

② 配置

spring.session.store-type=redis
server.servlet.session.timeout=30m
spring.redis.host=192.168.1.100

③ 主启动类添加注解@EnableRedisHttpSession

④ 存在的问题

现在存在的问题是子域名下会保存cookie,但是在父域名中却没有,我们希望只要在子域名下的cookie,父域名也能感知到。

  • 由于默认使用jdk进行序列化,通过导入RedisSerializer修改为json序列化
  • 并且通过修改CookieSerializer扩大session的作用域至**.test.com
@Configuration
public class TestSessionConfig {

    @Bean // redis的json序列化
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }

    @Bean // cookie
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setCookieName("GULISESSIONID"); // cookie的键
        serializer.setDomainName("test.com"); // 扩大session作用域,也就是cookie的有效域
        return serializer;
    }
}

使用SpringSession其实还存在Cookie的跨域问题,无法跨级,只能实现二级域名的跨域,多系统使用单点登录可以解决这个问题。

二、单点登录

分布式系统登录解决方案单点登录流程如下:
在这里插入图片描述
详细UML图:
在这里插入图片描述

拦截器代码:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HuCheng1997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值