基於redis解決session分布式一致性問題


1.session是什么

當用戶在前端發起請求時,服務器會為當前用戶建立一個session,服務器將sessionId回寫給客戶端,只要用戶瀏覽器不關閉,再次請求服務器時,將sessionId傳給服務器,

服務器會根據sessionId找到與之對應的session為其服務。

 如果是分布式部署時,session存儲在服務器端,下次用戶請求過來,通過負載均衡,可能會分發到其他服務器節點;所以,需要解決session一致性的問題,

使用redis來實現分布式session,個人理解是將session存放到redis中,每次請求過來時,會從redis讀取session信息

 

2.代碼實現

 ①.maven需要引入的依賴

  

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

②.配置文件指定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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM