分布式Session共享解决方案

1.session复制

在这里插入图片描述

2.浏览器本地存储

在这里插入图片描述

3.负载均很Hash-IP一致性

在这里插入图片描述

4.服务端同一存储

在这里插入图片描述
这里采用服务端同一存储的方式解决分布式Session共享问题

演示存在的问题

环境准备
1.创建三个服务器
在这里插入图片描述
ac为认证服务器,oth1、oth2分辨扮演其他业务服
2.设置本地域名

C:\Windows\System32\drivers\etc

在这里插入图片描述
这里设置域名也是模拟线上环境,因为不同域名存在session跨域问题,
3.导入依赖-这里的依赖

4.编写伪代码
ac服务器

login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form action="/login" method="post">
    <ul>
        <li class="top_1">
            <input type="text" name="username" placeholder=" 邮箱/用户名/已验证手机" class="user" />
        </li>
        <li>
            <input type="password" name="password" placeholder=" 密码" class="password" />
        </li>
        <li class="ent"><button type="submit" class="btn2"><a>&nbsp; &nbsp;</a></button></li>
    </ul>
</form>
</body>
</html>



ok.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ac-ok</title>
</head>
<body>
登录成功!!!
欢迎[[${session.data}]]
</body>
</html>

controller
@PostMapping("/login")
public String list(UserEntity userEntity, HttpSession session){
	log.debug("ac");
    UserEntity userRes=userService.query(userEntity);
    session.setAttribute("data","ac");
    log.debug(userRes.toString());
    return "ok";
}
//这里还缺一个login.html的视图解析器
//自己创建一个/映射一下

oth1服务器

oth1.html
 <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>oth1-ok</title>
</head>
<body>
登录成功!!!
欢迎[[${session.data}]]
</body>
</html>

 controller
 @GetMapping("/Oth1")
    public String list( HttpSession session){
        log.debug("Oth1");
        return "oth1";
    }

oth2服务器

oth2.html
 <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>oth2-ok</title>
</head>
<body>
登录成功!!!
欢迎[[${session.data}]]
</body>
</html>

 controller
 @GetMapping("/Oth2")
    public String list( HttpSession session){
        log.debug("Oth2");
        return "oth2";
    }

5.访问测试
这里采用火狐浏览器,其实我个人比较喜欢谷歌浏览器,但是公司有项目开发,还有一些个人账号信息存储在谷歌浏览器里面,不想被清空数据从新登陆,所以就用火狐这个备胎了!!!

AC登陆
在这里插入图片描述
登陆成功
在这里插入图片描述
登陆ac服务器成功,取的ac服务器的session

访问Oth1界面
在这里插入图片描述
这里虽然存在session但是在代码里面没有给Oth1服务器的session中存值

访问Oth2界面
在这里插入图片描述
这个Oth2服务器索性连session都没有

问题分析
不同服务器间session不共享,不同域名下session数据不共享,controller默认不携带session数据!
这里不同服务器session数据不共享还好理解,但是不同域名下session数据不共享就有点懵逼,演示一下,把session的作用域扩大到test.com范围在尝试,服务器不做变动!
在这里插入图片描述
在浏览器上将ac的session的域范围扩大为.test.com然后在Oth1、Oth2界面刷新,查看到Oth1、Oth2的cookie中确实多出的test.com的session,那么Oth1、Oth2的cookie中都存在session那么就能理所应当像ac一样取出session中的值,渲染为111,这里其实并不是,虽然session的域范围Oth1、Oth2确实是有了,但是在html界面渲染时Oth1、Oth2服务器的session里面并没有存在这样的值,所以Oth1、Oth2的html界面在服务器渲染后的session的值也是没有的!

解决session数据共享

session数据共享问题,spring为我们提供了非常成熟的技术方案!SpringSession,使用redis做session的统一存储,让各服务器都能共享redis中的session数据

1.导入MVN依赖

 		<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>

2.开启SpringSession
在这里插入图片描述
3.配置YML
在这里插入图片描述

  session:
    store-type: redis


servlet:
    session:
      timeout: 30m

4.测试访问
查看登录后的AC服务器session
在这里插入图片描述
查看redis在这里插入图片描述
这里现在分配的作用域是子域名的,现在还不能跨域共享数据

5.手动修改ac的session的作用域
在这里插入图片描述
6.刷新Oth2界面,服务器不做任何变动
在这里插入图片描述
这里Oth2服务器的代码没动,浏览器刷新Oth2的时候会检测当前域名,上个步骤中将AC的二级ac.test.com的作用域设置为了test.com所以Oth2.test.com也会获得父域名下的session数据,这里我们是手动修改的session的作用域,那么我们在后端用代码实现!

1.默认令牌为session=xxxxxxxxxxxxxx
2.作用域为当前服务器访问域名

补充:这里由于是演示代码,session中存储的是简单字符串,如果在多系统环境中,不同语言的数据类型不一样,会导致数据无法解析,那么可以是采用JSON来解决数据兼容性问题

解决问题

添加SpringSession配置类

@Configuration
public class SessionConfig {
    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        cookieSerializer.setDomainName("test.com");
        cookieSerializer.setCookieName("TESTSESSION");
        return cookieSerializer;
    }

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

重启服务器
访问ac
在这里插入图片描述
这里的session的作用域为test.com
查看Oth2
在这里插入图片描述
这里访问直接能够拿到父域test.com的值

Redis中session的JSON序列化
在这里插入图片描述
分布式Session的解决方案就演示完成了,后面还会结合单点登录,整合SpringSecurity来做一个整体的案例

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员劝退师-TAO

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

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

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

打赏作者

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

抵扣说明:

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

余额充值