SpringBoot之使用Spring-Session實現session共享(nginx+redis)


一、Spring-Session使用的場景

HttpSession是通過Servlet容器進行創建和管理的,在單機環境中。通過Http請求創建的Session信息是存儲在Web服務器內存中,如Tomcat/Jetty。假如當用戶通過瀏覽器訪問應用服務器,session信息中保存了用戶的登錄信息,並且session信息沒有過期失,效那么用戶就一直處於登錄狀態,可以做一些登錄狀態的業務操作。

但是現在很多的服務器都采用分布式集群的方式進行部署,一個Web應用,可能部署在幾台不同的服務器上,通過LVS或者Nginx等進行負載均衡(一般使用Nginx+Tomcat實現負載均衡)。此時來自同一用戶的http請求將有可能被分發到不同的web站點中去(如:第一次分配到A站點,第二次可能分配到B站點)。那么問題就來了,如何保證不同的web站點能夠共享同一份session數據呢?

假如用戶在發起第一次請求時候訪問了A站點,並在A站點的session中保存了登錄信息,當用戶第二次發起請求,通過負載均衡請求分配到B站點了,那么此時B站點能否獲取用戶保存的登錄的信息呢?答案是不能的,因為上面說明,session是存儲在對應Web服務器的內存的,不能進行共享,此時spring-session就出現了,來幫我們解決這個session共享的問題!

如何進行Session共享呢?

簡單點說就是請求http請求經過Filter鏈,根據配置信息過濾器將創建session的權利由tomcat交給了spring-session中的SessionRepository,通過spring-session創建會話,Session的內容統一存儲在一個數據庫(如MySQL)或緩存(如Redis,Mongo)中。

當然使用Nginx的ip_hash策略也可以解決session同步的問題。

在使用Nginx的ip_hash策略時候,每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個后端服務器,這樣就解決session的同步問題。

大神文章地址:https://blog.csdn.net/qq_28602957/article/details/61615876

二、在springboot中使用spring-session

1、引入Maven依賴

復制代碼
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
       <!--spring boot-->
       <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--spring session-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    </dependencies>         
復制代碼

2、配置application.properties

server.port=8080
spring.redis.host=localhost
spring.redis.port=6379

#spring session使用存儲類型,默認就是redis所以可以省略
spring.session.store-type=redis

3、在啟動類中加入注解

復制代碼
@EnableCaching
@EnableRedisHttpSession
@SpringBootApplication
public class SpringsessionApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringsessionApplication.class, args);
    }

}
復制代碼

4、編寫控制器

復制代碼
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;

@RestController
public class IndexController {

    @RequestMapping("/show")
    public String show(HttpServletRequest request){
        return "I'm " + request.getLocalPort();
    }


    @RequestMapping(value = "/session")
    public String getSession(HttpServletRequest request) {
        request.getSession().setAttribute("userName", "admin");
        return "I'm " + request.getLocalPort() + " save session " + request.getSession().getId();
    }

    @RequestMapping(value = "/get")
    public String get(HttpServletRequest request) {
        String userName = (String) request.getSession().getAttribute("userName");
        return "I'm " + request.getLocalPort() + " userName :" + userName;
    }
    
}
復制代碼

5、配置nginx

復制代碼
    upstream  ngixServers{
        server localhost:8081;
        server localhost:8082;
    }
    server {
        listen       8888;
        server_name  localhost;
        location / {
        proxy_pass http://ngixServers;
        }
    }
復制代碼

6、測試結果

a)啟動redis

b)啟動nginx

c)修改springboot的啟動方式,允許啟動多個示例。

d)修改application.properties中的端口號,改為8081,啟動tomcat。

e)修改application.properties中的端口號,改為8082,啟動tomcat。

訪問地址:http://localhost:8888/show  可見如下結果(出現不分先后):

 刷新可見:

 以上運行結果說明負責均衡已經好使,兩台服務器都可以正常訪問。

f)接下來訪問地址:http://localhost:8888/session,將session寫入一個服務器。(服務器可能是8081,也可能是8082)

 g)訪問地址:http://localhost:8888/get ,多次刷新可見兩個服務器均能獲得session。(此session存在與redis中)

 

或者

到此,使用nginx實現負載均衡和使用spring-session+redis實現session共享就完成了。可以使用命令或者在RedisDesktopManager中查看redis中存儲的session信息!

參考大神文章:

https://www.cnblogs.com/aflyun/p/8532210.html

https://www.cnblogs.com/shyroke/p/8039430.html


免責聲明!

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



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