Session

概述

Session是服務器端使用的一種記錄客戶端狀態的機制,若是說Cookie機制是經過檢查客戶身上的「通行證」來肯定客戶身份的話,那麼Session機制就是經過檢查服務器上的「客戶明細表」來確認客戶身份。Session至關於程序在服務器上創建的一份客戶檔案,客戶來訪的時候只須要查詢客戶檔案表就能夠了。html

Session原理

Session是基於Cookie來工做的,同一個客戶端每次訪問服務器時,只要當瀏覽器在第一次訪問服務器時,服務器設置一個id並保存一些信息(例如登錄就保存用戶信息,視具體狀況),並把這個id經過Cookie存到客戶端,客戶端每次和服務器交互時只傳這個id,就能夠實現維持瀏覽器和服務器的狀態,而這個ID一般是NAME爲JSESSIONID的一個Cookie。若是客戶端瀏覽器將Cookie功能禁用,或者不支持Cookie怎麼辦?例如,絕大多數的手機瀏覽器都不支持Cookie。Java Web提供了其它多種實現方式。前端

Session實現方式

經過URL傳遞SessionID

若是客戶端瀏覽器將Cookie功能禁用,或者不支持Cookie怎麼辦?例如,絕大多數的手機瀏覽器都不支持Cookie。Java Web提供了另外一種解決方案:URL地址重寫URL地址重寫的原理是將該用戶Session的id信息重寫到URL地址中,即在文件名的後面,在URL參數的前面添加了字符串「;jsessionid=XXX」,其中XXX爲Session的id。服務器可以解析重寫後的URL獲取Session的id。這樣即便客戶端不支持Cookie,也可使用Session來記錄用戶狀態。java

經過Cookie傳遞SessionID

經過SSL傳遞SessionID

根據javax.servlet.request.ssl_session屬性值設置SessionID。redis

經過隱藏表單傳遞SessionID

表單隱藏字段,就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。瀏覽器

<form name="testform" action="/xxx">
    <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
    <input type="text">
</form>

session生命週期

在談論session機制的時候,經常聽到這樣一種誤解「只要關閉瀏覽器,session就消失了」。對session來講也是同樣的,除非程序通知服務器刪除一個session,不然服務器會一直保留,程序通常都是在用戶作logout的時候發個指令去刪除session。然而瀏覽器歷來不會主動在關閉以前通知服務器它將要關閉,所以服務器根本不會有機會知道瀏覽器已經關閉,之因此會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個 session id就消失了,再次鏈接服務器時也就沒法找到原來的session。若是服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求頭,把原來的session id發送給服務器,則再次打開瀏覽器仍然可以找到原來的session。緩存

偏偏是因爲關閉瀏覽器不會致使session被刪除,迫使服務器爲seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就能夠認爲客戶端已經中止了活動,纔會把session刪除以節省存儲空間。tomcat

session在下列狀況下被刪除安全

  • 程序調用HttpSession.invalidate()
  • 距離上一次收到客戶端發送的session id時間間隔超過了session的最大有效時間
  • 服務器進程被中止

與Cookie區別

  • cookie數據存放在客戶的瀏覽器上,session數據放在服務器上,可是服務端的session的實現對客戶端的cookie有依賴關係的;
  • cookie不是很安全,別人能夠分析存放在本地的COOKIE並進行COOKIE欺騙,考慮到安全應當使用session;
  • session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能。考慮到減輕服務器性能方面,應當使用COOKIE;
  • 單個cookie在客戶端的限制是3K,就是說一個站點在客戶端存放的COOKIE不能超過3K;

跨窗口會話跟蹤

一般session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的sessionid,這樣咱們信息共享的目的就達不到了,此時咱們能夠先把sessionid保存在persistent cookie中,而後在新窗口中讀出來,就能夠獲得上一個窗口SessionID了,這樣經過session cookie和persistent cookie的結合咱們就實現了跨窗口的session tracking(會話跟蹤)。服務器

分佈式Session管理

      Web應用在單機部署的狀況下,Session是被單個應用服務器存儲管理的,因爲只有一個應用服務器,用戶的全部請求都是經過它進行響應處理的,因此可以很容易實現會話跟蹤和保持。隨着業務量的增加,系統架構須要作出調整以適應發展的須要,可能會使用分佈式架構或微服務架構,不管使用哪一種架構方式,應用系統單機部署的模式已經不能知足需求,因此會將應用系統部署到多臺應用服務器上,用戶的請求也會經過負載均衡轉發到某個具體應用服務器上執行,可能會出如今A1系統登陸後建立並保存Session,再次發起請求,請求被轉發到A2系統上顯示未登陸的狀況,此時單機部署模式下的Session機制已不能知足要求。因此,在分佈式架構或微服務架構下,必須保證一個應用服務器上保存Session後,其它應用服務器能夠同步或共享這個Session。cookie

關於有狀態服務和無狀態服務

有狀態和無狀態服務是兩種不一樣的服務架構,二者的不一樣之處在於對於服務狀態的處理。服務狀態是服務請求所需的數據,它能夠是一個變量或者一個數據結構。無狀態服務不會記錄服務狀態,不一樣請求之間也是沒有任何關係;而有狀態服務則反之。

典型的無狀態服務的例子就是Http協議。例如,要實現一個計算求和的服務,每次請求都將求和的兩個值傳送給服務端,而後服務端計算求和結果,並返回給客戶端,服務端不保存任何信息,這樣的服務就屬於無狀態服務。有狀態服務則相反,服務會存儲請求上下文相關的數據信息,前後的請求是能夠有關聯的。在Web 應用中,常常會使用Session來維繫登陸用戶的上下文信息。雖然Http協議是無狀態的,可是藉助於Cookie和Session,可使http服務轉換爲有狀態服務。

無狀態的服務很容易橫向擴展,只須要在負載均衡以後增長節點就能夠處理更多請求,同時具備更好的維護性和容錯性(假若有狀態,若保有用戶信息的服務器宕機,那麼該用戶最近的全部交互操做將沒法被透明地移送至備用服務器上,除非該服務器時刻與主服務器同步所有用戶的狀態信息)。可是無狀態服務也不是天衣無縫的,其中一個缺點就是和數據層之間的請求延遲,以及爲了解決這種延遲增長緩存所帶來的複雜性和一致性問題最理想的狀態存放點,要麼在最前端,要麼在最底層的存儲層。只有將 IO 密集型程序和CPU密集型程序分離,纔是通往「無狀態」真正的出路。一旦分離後,CPU 密集型的程序天然就是「無狀態」了。如此也能更好的作「彈性擴容」。由於常見的須要「彈性擴容」的場景通常指的就是 CPU負荷過大的時候。

Session複製

在支持Session複製的Web服務器上,經過修改Web服務器的配置,能夠實現將Session同步到其它Web服務器上,達到每一個Web服務器上都保存一致的Session。
優勢:代碼上不須要作支持和修改。
缺點:須要依賴支持的Web服務器,一旦更換成不支持的Web服務器就不能使用了,在數據量很大的狀況下不只佔用網絡資源,並且會致使延遲。
適用場景:只適用於Web服務器比較少且Session數據量少的狀況。
可用方案:開源方案tomcat-redis-session-manager,暫不支持Tomcat8。

Session粘滯

將用戶的每次請求都經過某種方法強制分發到某一個Web服務器上,只要這個Web服務器上存儲了對應Session數據,就能夠實現會話跟蹤
優勢:使用簡單,沒有額外開銷。
缺點:一旦某個Web服務器重啓或宕機,相對應的Session數據將會丟失,並且須要依賴負載均衡機制。
適用場景:對穩定性要求不是很高的業務情景。

Session集中管理

在單獨的服務器或服務器集羣上使用緩存技術,如Redis存儲Session數據,集中管理全部的Session,全部的Web服務器都從這個存儲介質中存取對應的Session,實現Session共享,經過剝離session,將一個有狀態服務轉換成無狀態服務,相對來講,Session集中管理更加可靠,使用也是最多的
優勢:可靠性高,減小Web服務器的資源開銷。
缺點:實現上有些複雜,配置較多。
適用場景:Web服務器較多、要求高可用性的狀況。
可用方案:開源方案Spring Session,也能夠本身實現,主要是重寫HttpServletRequestWrapper中的getSession方法。

基於Cookie管理

這種方式每次發起請求的時候都須要將Session數據放到Cookie中傳遞給服務端
優勢:不須要依賴額外外部存儲,不須要額外配置。
缺點:不安全,易被盜取或篡改;Cookie數量和長度有限制,須要消耗更多網絡帶寬。
適用場景:數據不重要、不敏感且數據量小的狀況。

參考連接

https://www.jianshu.com/p/3dd4e06bdfa4

https://www.jianshu.com/p/3f2c12848efb

http://www.javashuo.com/article/p-ncjlxgps-ew.html

https://www.infoq.cn/article/Acxp9dIwWmwm1_stwPzA

https://zhuanlan.zhihu.com/p/25874641

http://book.51cto.com/art/201807/578642.htm

相關文章
相關標籤/搜索