您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)Spring Session Redis 在不同服務(wù)間共享 Session 時的類共享方案的示例分析,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
當(dāng)在多服務(wù)之間使用 Spring Session Redis 進(jìn)行 Session 共享要非常小心,因為它很不安全,很有可能導(dǎo)致整個服務(wù)實例不可用,無法處理任何請求。其中比較危險的地方就是在進(jìn)行序列化,反序列化的時候(這種類型的錯誤尤其容易在沒有開發(fā)規(guī)范的團(tuán)隊內(nèi)發(fā)生,就是什么樣的數(shù)據(jù)可以往共享存儲里面存,什么樣的不能存。存的時候要以什么樣的格式去存,這些都要有規(guī)定才比較安全。因為共享存儲是會影響到別人的不僅僅是為了自己的服務(wù)用起來方便)。RedisSerializer 接口的實現(xiàn)都是在序列化和反序列化出錯的時候直接拋出異常從而導(dǎo)致整個請求錯誤。
public interface RedisSerializer<T> { /** * Serialize the given object to binary data. * * @param t object to serialize * @return the equivalent binary data */ byte[] serialize(T t) throws SerializationException; /** * Deserialize an object from the given binary data. * * @param bytes object binary representation * @return the equivalent object instance */ T deserialize(byte[] bytes) throws SerializationException; }
下面用一張圖來說明我遇到的問題。Spring Session 的誕生老實說并不是為了分布式系統(tǒng),而是為集群系統(tǒng)提供了一種 Session 解決方案。但是我們把 Spring Session 用在了分布式系統(tǒng)上用以解決 Session 共享的問題老實說本身就是有點難為人家 Spring Session 了 。
Spring Session 實現(xiàn) Session 共享的大致原理如下圖所示 , 使用一個 Filter 來攔截所有請求,在攔截到請求之后對 HttpServletRequest 和 HttpServletResponse 進(jìn)行包裝 (HttpServletRequestWrapper , HttpServletResponseWrapper)。在包裝中對 session 進(jìn)行控制 ,將 session 數(shù)據(jù)都存儲在第三方存儲當(dāng)中。
在了解了 Spring Session 的工作原理后再去考慮這個問題就有頭緒了 。還是通過圖形的方式來做大概的說明。
學(xué)習(xí) Spring Session 的 SessionRepositoryFilter 的實現(xiàn)方式 , 添加一個 Filter 順序在 SessionRepositoryFilter 之后 , 在攔截過程中包裝 HttpServletRequest , 重寫 getSession(boolean create) 和 getSession() 方法, 自定義一個 SafetyHttpSessionWrapper 包裝 Session ,重寫 setAttribute(String name , Object value) 函數(shù) , 在保存屬性成功后利用 redis 的發(fā)布訂閱機制發(fā)送消息到 redis , 消息的內(nèi)容為所保存對象的 .class 文件數(shù)據(jù)。在消息訂閱端 , 接收到消息后利用 javassist 和 net.bytebuddy.dynamic.loading.ByteArrayClassLoader 將 .class 文件數(shù)據(jù)加載轉(zhuǎn)換成 Class 的實例對象,但是這個 Class 實例的范圍被限定在 ByteArrayClassLoader 中 , 而這個 ByteArrayClassLoader 是提供給 RedisSerializer 內(nèi)部使用的 , 比如 JdkSerializationRedisSerializer , GenericJackson2JsonRedisSerializer 都需要使用到 ClassLoader 。這樣當(dāng) 服務(wù)A 在存儲任何自定義的對象在 Session 中時, 訪問服務(wù) B 也不會出現(xiàn)讀取 Session 反序列化 ClassNotFoundException 的錯誤了。
看完上述內(nèi)容,你們對Spring Session Redis 在不同服務(wù)間共享 Session 時的類共享方案的示例分析有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。