Springboot Session共享 演示

本文參考 Spring Boot 一個依賴搞定 session 共享,沒有比這更簡單的方案了!

在傳統的單服務架構中,只有一個服務器,那就不會存在session共享的問題,但如果在分佈式/集羣項目中,session共享則是一個必須面對的問題。

這樣就會出現一個問題,比如說,當客戶端發起了一個請求,這個請求到達Nginx之後,被轉發到了服務器A,然後在服務器A上往session保存了一份數據,下次又來一個請求,這個請求被轉發到 Tomcat B 上,此時再去 Session 中獲取數據,發現沒有之前的數據。對於這一類問題的解決,思路很簡單,就是將各個服務之間需要共享的數據,保存到一個公共的地方(主流方案就是 Redis):

  • 當所有 Tomcat 需要往 Session 中寫數據時,都往 Redis 中寫,當所有 Tomcat 需要讀數據時,都從 Redis 中讀。這樣,不同的服務就可以使用相同的 Session 數據了。

  • 這樣的方案,可以由開發者手動實現,即手動往 Redis 中存儲數據,手動從 Redis 中讀取數據,相當於使用一些 Redis 客戶端工具來實現這樣的功能,毫無疑問,手動實現工作量還是蠻大的。

  • 一個簡化的方案就是使用 Spring Session 來實現這一功能,Spring Session 就是使用 Spring 中的代理過濾器,將所有的 Session 操作攔截下來,自動的將數據 同步到 Redis 中,或者自動的從 Redis 中讀取數據。

  • 對於開發者來說,所有關於 Session 同步的操作都是透明的,開發者使用 Spring Session,一旦配置完成後,具體的用法就像使用一個普通的 Session 一樣。

演示

創建一個springboot項目

依賴

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

        <!--用於連接redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--用於使用redis接管session-->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--工具類,非必需-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.1.0</version>
        </dependency>

application.yml

server:
  port: 8088
spring:
  redis:
    host: localhost
    port: 6379

IndexController

@RestController
@RequestMapping(value = "/")
public class IndexController {

    @Value("${server.port}")
    private String port;
    private String username = "wangxianlin";
    private String password = "123456";
    private String nickname = "Halo";


    @RequestMapping(value = "/login")
    public Map<String, Object> getSession(HttpServletRequest request,@RequestParam("user") String user,@RequestParam("pwd") String pwd) {
        Map<String, Object> map = new HashMap<>();
        if (username.equals(user) && password.equals(pwd)){
            request.getSession().setAttribute("user", "當前登錄用戶是:"+nickname);
            map.put("msg", "登錄成功");
            map.put("port",port);
        }else {
            map.put("msg", "賬號或密碼錯誤");
        }
        return map;
    }

    @RequestMapping(value = "/get")
    public Map<String, Object> get(HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        String user = (String) request.getSession().getAttribute("user");
        map.put("msg", StrUtil.isEmpty(user)?"用戶未登錄":user);
        map.put("port",port);
        return map;
    }
}

在啓動類上加上註解
@EnableRedisHttpSession

將項目打成jar包

啓動項目

前提:redis 是否已經開啓?

將jar 分別以 8088和8089端口進行啓動
java -jar --server.port=8088
java -jar --server.port=8089

配置nginx

 upstream web-server { 
        server localhost:8088;  
        server localhost:8089;
    }

    server {
        listen       9000;
        server_name  localhost;
        location / {
            proxy_pass http://web-server;
        }
  }

啓動nginx

由於我這裏有三個nginx配置文件,然後我想啓動nginx-origanal.conf 咋辦呢?


命令 人家早就給我們安排好了,我們只需要這樣。

測試

未登錄狀態下

http://localhost:9000/get

登錄:

http://localhost:9000/login?user=wangxianlin&pwd=123456
http://localhost:9000/get

看一下redis裏面

以上內容參考於: Spring Boot 一個依賴搞定 session 共享,沒有比這更簡單的方案了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章