SpringSession - 分佈式Session解決方案及SpringSession基本使用

分佈式Session的幾種解決方案

1、Session複製

在這裏插入圖片描述
Tomcat服務器互相同步session。
優點:
web-server (Tomcat) 原生支持,只需要修改配置文件
缺點:
1、session同步需要數據傳輸,佔用大量網絡帶寬,降低了服務器羣的業務處理能力
2、任意一臺web-server保存的數據都是所有web-server的sesdion總和,受到內存限制無法水平擴展更多的web-server
3、大型分佈式集羣情況下,由於所有web-server都全量保存數據,所以此方案不可取。

2、客戶端存儲

在這裏插入圖片描述
將session存儲在cookie中。
優點:
服務器不需存儲session,用戶保存自己的session信息到cookie中,節省服務端資源。
缺點:
這只是一種思路,不會使用該方式,具體原因如下:
1、每次http請求,攜帶用戶在cookie中的完整信息,浪費網絡帶寬。
2、session數據放在cookie中,cookie有長度限制4K,不能保存大量信息。
3、session數據放在cookie中,存在泄漏、算改、竊取等安全隱患。

3、Hash一致性

利用ip_hash的一致性,瀏覽器不變,IP不變,讓每一次訪問都落在同一個服務器上。同時也可以配合id值,比如圖中的sid=456的請求每次落在第一個服務器,sid=123的請求每次落在第二個服務器。
優點:
1、只需要改nginx配置,不需要修改應用代碼。
2、負載均衡,只要hash屬性的值分佈是均勻的,多臺web-server的負載是均衡的。
3、可以支持web-server水平擴展(session同步法是不行的,受內存限制)。
缺點:
1、session還是存在web-server中的,所以web-server重啓可能導致部分session丟失,影響業務,如部分用戶需要重新登錄。
2、如果web-server水平擴展,rehash後session重新分佈,也會有一部分用戶路由不到正確的session。
但是以上缺點問題也不是很大,因爲session本來都是有有效期的。所以這兩種反向代理的方式可以使用。

4、統一存儲

在這裏插入圖片描述
session存儲到數據庫(Redis)中,每次都從數據庫中獲取。
優點:
1、沒有安全隱患
2、可以水平擴展,數據庫/緩存水平切分即可
3、web-server重啓或者擴容都不會有session丟失
缺點:
增加了一次網絡調用,並且需要修改應用代碼;如將所有的getSession方法替換爲從Redis查數據的方式,redis獲取數據比內存慢很多
上面缺點可以用SpringSession完美解決

5、不同服務,子域Session共享

jsessionid這個cookie默認是當前系統域名的。當我們分拆服務,不同域名部署的時候,我們可以使用如下解決方案:
在這裏插入圖片描述
第一次使用Session的時候,命令瀏覽器Cookie保存卡號(JESSIONID),以後瀏覽器訪問哪個網站都會帶上這個網站的cookie。
髮卡的時候指定域名爲父域名,即使是子域系統發的卡,也能讓父域直接使用。
給父域發jesessionid卡,子域共享。比如給liuchengyin.com髮卡,auth.liuchengyin.com、item.liuchengyin.com共享。

SpringSession的使用

SpringBoot整合SpringSession。官方文檔:spring-session-data-redis文檔
在這裏插入圖片描述

1、引入spring-session-data-redis依賴

<!-- 整合SpringSession完成Session共享問題 -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
2、配置文件 - properties或yml

所有使用分佈式Session的微服務都要配置,當然肯定還需要配置Redis相關的內容。比如在A服務中存儲,在B、C服務中獲取,A、B、C服務都需要配置。

# Session保存類型 - Redis
spring.session.store-type=redis
# Session過期時間 - 默認30分鐘
server.servlet.session.timeout=30m
# 同時,也需要配置Redis連接信息
spring.redis.host=192.168.200.134
spring.redis.port=6379
3、配置Redis - 如果已經配置過則無需再配置
@EnableRedisHttpSession  // 使用RedisHttpSession,
public class Config {
	@Bean
	public LettuceConnectionFactory connectionFactory() {
		return new LettuceConnectionFactory(); 
	}
}
4、配置作用域和Session序列化
@Configuration
public class LiuchengyinSessionConfig {
    /**
     * 設置作用域
     */
    @Bean
    public CookieSerializer cookieSerializer(){
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
		/*
			設置父域 - liuchengyin.com
			則xxx.liuchengyin.com都會共享
		*/
        cookieSerializer.setDomainName("liuchengyin.com");
        cookieSerializer.setCookieName("LCYSESSION");  // 自定義SessionId
        return cookieSerializer;
    }

    /**
     * JSON序列化 - 使用FastJson,需要引入Fastjson的依賴
     */
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
        return new GenericFastJsonRedisSerializer();
    }
}
5、正常調用session存儲數據即可
public String saveData(HttpSession session, Long id){
    // 從數據庫中查詢數據
    User user = userDao.selectUserById(id);
    // 保存數據
    session.setAttribute("loginUser",user);
    return user;
}
6、查看Redis中保存的數據

在這裏插入圖片描述

7、查看瀏覽器Cookie

在這裏插入圖片描述
此時就可以去.liuchengyin.com的子域也可以獲取到session

SpringSession原理淺析

原理其實就是運用了裝飾者模式。且Redis中的Session也有過期時間,和原生Session一致,會自動續期。

@EnableRedisHttpSession註解

導入了RedisHttpSessionConfiguration配置
在這裏插入圖片描述
RedisHttpSessionConfiguration添加了RedisOperationsSessionRepository組件,即使用Redis操作session,session的增刪改查封裝類。即SessionRepository ====>>> 【RedisOperationsSessionRepository】
在這裏插入圖片描述
RedisHttpSessionConfiguration繼承自SpringHttpSessionConfiguration,可以在SpringHttpSessionConfiguration中看到一個過濾器SessionRepositoryFilter<? extends Session>,即Session存儲過濾器,每個請求過來都必須經過Filter
在這裏插入圖片描述
1、創建Session的時候就自動從容器中獲取了SessionRepository
2、原始的request和response都被包裝成SessionRepositoryRequestWrapper和SessionRepositoryResponseWrapper
3、以後獲取session,即通過reuqest.getSession()。就相當於調用wrappedRequest.getSession()。如果wrappedRequest.getSession()有自定義的實現,就相當於Session的獲取方法改變了。
4、wrappedRequest.getSession()就是從SessionRepository獲取到的。

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