分布式Session的实现和原理

一、为什么需要session

在这里插入图片描述
举例:比如张三登录的A网页然后进行用户名和密码登录之后,当跳转到B页面的时候,如果B页面也需要登录信息。这个时候由于HTTP协议是一个无状态协议,这样就需要张三再次登录。因此需要在HTTP协议之上进行扩展,这个时候就引入了cookie和session。

二、Cookie与Session

1. cookie 是什么?

  • 是存储于用户主机浏览器中的一小段文本文件
  • 由服务器端生成,发送给浏览器,KV形式存储

2. Session 是什么?

  • 字面理解为 “会话
  • 保存在服务端的数据结构

3. Session 和 cookie 的区别

在这里插入图片描述

4. Session 的工作原理

在这里插入图片描述

5. 简单的代码实现session

@RestController
public class TestController {

    @RequestMapping(value = "/first-index", method = RequestMethod.GET)
    public String helloWorld(){
        return "hello, springboot!!!";
    }

    static Map<String, String> passwordMap = new HashMap<>();

    static {
        passwordMap.put("zhangsan", "123");
        passwordMap.put("lisi", "321");
    }

    @RequestMapping("/index")
    @ResponseBody
    public String index(HttpServletRequest request){
        HttpSession httpSession = request.getSession();
        //从session中获取用户登录信息
        Boolean isLogin = (Boolean)httpSession.getAttribute("isLogin");
        if(isLogin != null && isLogin){
            return "欢迎 " + httpSession.getAttribute("username")
                + " 进入首页!";
        }else {
            return "请登录!";
        }
    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    @ResponseBody
    public String login(HttpServletRequest request,
                        @RequestParam("username")String username,
                        @RequestParam("password")String password){
        //1、验证用户名和密码
        if(!passwordMap.containsKey(username)){
            return "请先注册";
        }
        if(!passwordMap.get(username).equalsIgnoreCase(password)){
            return "密码错误";
        }
        //2、生成session
        HttpSession httpSession = request.getSession();
        //3、将登录信息写入session
        httpSession.setAttribute("isLogin", Boolean.TRUE);
        httpSession.setAttribute("username", username);
        //4、返回
        return "welcome " + username;
    }
}

在这里插入图片描述
根据源码可得知,当创建session的时候 默认会生成一个cookiesName=“JSESSIONID”

三、分布式session

1. 分布式session失效

单体服务器到分布式环境集群的时候,用户第一次访问路由到了A服务器登录信息写入到A服务器,当用户再次访问,网关路由到了B服务器,然后B服务器没有保存用户信息,这样导致session失效
在这里插入图片描述

2. session粘连,解决session失效

在这里插入图片描述
思路:
反向代理层让同一个用户的请求保证落在一台server上呢?
方法一:四层代理hash。反向代理层使用用户ip来做hash,以保证同一个ip的请求落在同一个server上(更推荐,保证传输层不引入业务层的逻辑)

方法二:七层代理hash。反向代理使用http协议中的某些业务属性来做hash,例如sid,city_id,user_id等,能够更加灵活的实施hash策略,以保证同一个浏览器用户的请求落在同一个server上

优点
只需要改nginx配置,不需要修改应用代码
可以支持server水平扩展
不足
server水平扩展,rehash后session重新分布,会有一部分用户路由不到正确的session,即使hash散列均匀,也不能保证server的负载均匀

3. session复制

在这里插入图片描述
思路:
多个server之间相互同步session,这样每个server之间都包含全部的session

优点:
只需要设定配置,应用程序不需要修改代码
不足:
session的同步需要数据传输,占内网带宽,有延时所有server都包含所有session数据,数据量受最小内存的sever限制,水平拓展能力差

4. session中心存储

在这里插入图片描述

四、redis实现分布式session

<dependency>  
   <groupId>org.springframework.boot</groupId>  
   <artifactId>spring-boot-starter-redis</artifactId> 
</dependency>
<dependency>  
    <groupId>org.springframework.session</groupId>  
    <artifactId>spring-session-data-redis</artifactId>  
</dependency> 
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class RedisSessionConfig {

}

在写完配置类后,前万记得要在在spring boot的启动类上写上注解@EnableRedisHttpSession

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值