面試官:分佈式環境下,如何實現 session 共享

先了解一下爲什麼會出現這種 session 共享的解決方案?

隨着互聯網公司的項目在微服務和分佈式的環境下進行的搭建,導致一個項目可能分別部署在幾個甚至很多的服務器集羣下,此時就會出現一個問題:

當用戶進行一個 session 會話的時候,比如一個用戶去登錄項目,一般的大公司的項目都是有 Nginx 進行反向代理的,

這裏簡單列舉一下 Nginx 常用的幾種反向代理策略:

  1. 輪詢策略,

  2. 權重比例策略,

  3. ip_hash 策略,

  4. 還可以自定義的策略,

在 Nginx 的反向代理下,一般會把用戶的請求分發到不同的服務器上,但是如果用戶請求的請求是存放在該請求的服務器 A 上,那麼該用戶的 sessionID 就存儲在該服務器上 JVM 的一個 ConcurrentHashmap 中,以 sessionID 爲 key。

但是如果此時用戶請求的一個服務模塊可能需要調用到服務器 B,當用戶發起請求的時候,此時的服務器 B 上並沒有存儲該用戶的 sessionID,所以就會再次讓用戶進行一個登陸操作。還有可能會導致用戶本來就想完成一個下單操作,但是卻還登陸了好幾次的情況。

所以 session 共享方案在分佈式環境和微服務系統下,顯得尤其重要。

解決方案一:基於 Nginx 的 ip_hash 負載均衡

其實就是對請求過來的 ip 地址對你的多少臺可用的服務器進行取模,然後就會把你的請求通過 Nginx 的反向代理給分發到對應的服務器上。(這裏會把可用的服務器放到一個數組中,如果取模得到的結果是幾,就把請求分到服務器數組中的下標爲幾的服務器上)

具體實現:

需要你在 Nginx.conf 文件中進行對應的修改,根據自己的可用服務器

upstream backend{
    ip_hash;
    server 192.168.128.1:8080 ;
    server 192.168.128.2:8080 ;
    server 192.168.128.3:8080 down;
    server 192.168.128.4:8080 down;
 
}
server {
    listen 8081;
    server_name test.csdn.net;
    root /home/system/test.csdn.net/test;
    location ^~ /Upload/upload {
    proxy_pass http://backend;
 
    }
 
}

這種實現的優缺點:

解決方案二:基於 Tomcat 的 session 複製

這個解決方案其實就是當用戶請求的時候,把產生的 sessionID 給複製到系統所有的服務器中,這樣就能保證當用戶請求的時候從服務器 A 可能調用到服務器 B 上的模塊的時候,也能保證服務 B 也有該用戶的 sessionID,這樣就不會再次讓用戶進行再次登錄操作了。也就解決問題了。

具體代碼中如何實現 session 複製呢?

使用 session 複製的優缺點:

解決方案三:使用 Redis 做緩存 session 的統一緩存

這種方案呢,其實就是把每次用戶的請求的時候生成的 sessionID 給放到 Redis 的服務器上。然後在基於 Redis 的特性進行設置一個失效時間的機制,這樣就能保證用戶在我們設置的 Redis 中的 session 失效時間內,都不需要進行再次登錄。推薦:250 期面試題

如何進行代碼的實現:

使用 Redis 實現 session 共享的優缺點:

其實還可以把 session 放到 cookie 中去,因爲每次用戶請求的時候,都會把自己的 cookie 放到請求中,所以這樣就能保證每次用戶請求的時候都能保證用戶在分佈式環境下,也不會在進行二次登陸。

_感謝閱讀,希望對你有所幫助 :) _

參考:網易雲課堂

來源:blog.csdn.net/qq_36520235/

article/details/87830929

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/9xOHoeIWx9gMpeZDMbEYDQ