基于redis解决session分布式一致性问题

1.session是什么

当用户在前端发起请求时,服务器会为当前用户建立一个session,服务器将sessionId回写给客户端,只要用户浏览器不关闭,再次请求服务器时,将sessionId传给服务器,

服务器会根据sessionId找到与之对应的session为其服务。

 如果是分布式部署时,session存储在服务器端,下次用户请求过来,通过负载均衡,可能会分发到其他服务器节点;所以,需要解决session一致性的问题,

使用redis来实现分布式session,个人理解是将session存放到redis中,每次请求过来时,会从redis读取session信息

 

2.代码实现

 ①.maven需要引入的依赖

  


    org.springframework.boot
    spring-boot-starter-web


    org.springframework.session
    spring-session

②.配置文件指定redis的ip和端口

spring.redis.host=172.18.66.45
spring.redis.port=6379

 

③.httpSession配置

package com.session.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
//maxInactiveIntervalInSeconds设置session有效时间,单位是秒;默认是30分钟
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=180)
public class SessionConfig {
    
    @Value("${spring.redis.host}")
    private String hostName;
    @Value("${spring.redis.port}")
    private int port;

    @Bean
    public JedisConnectionFactory connectionFactory() {
        JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
        connectionFactory.setPort(port);
        connectionFactory.setHostName(hostName);
        System.out.println("获取到的hostName是:"+hostName + ",port :"+port);
        return connectionFactory;
    }
}

 

再实现一个controller,就可以模拟实际业务场景写session、根据session校验用户是否登录

package com.session.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SessionController {

    //模拟第一次登陆时,保存session
    @RequestMapping(value="/login")
    public String login(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String str = (String) session.getAttribute("userInfo");
        if(str == null || "".equals(str)) {
            session.setAttribute("userInfo", "mpy test session");
            return "用户登录成功-success";
        }else{
            return "session中存在数据,用户已登录";
        }
    }

    /*该方法模式登陆之后,调用业务接口
*在实际的业务场景中,可以使用拦截器,对每次请求进行判断,校验用户是否登录、session是否过期
*/ @RequestMapping(value="/getSession") public String getSession(HttpServletRequest request) { HttpSession session = request.getSession(); String str = (String) session.getAttribute("userInfo"); if(str == null || "".equals(str)) { return "session中没有数据,请登录"; }else{ //已登录用户,进行其他业务代码的处理 System.out.println("session中的属性是:"+str); return str; } } @RequestMapping(value="/logout") public String logout(HttpServletRequest request) { HttpSession session = request.getSession(); String str = (String) session.getAttribute("userInfo"); if(str != null && "".equals(str)) { session.invalidate(); } return "退出成功"; } }

 

 @EnableRedisHttpSession和spring-session的实现原理还有待研究学习

具体的代码,已经上传至GitHub,https://github.com/mapy95/spring-session.git

你可能感兴趣的:(基于redis解决session分布式一致性问题)