Session學習小結

零、從會話技術講起

我理解的一次會話就是打開瀏覽器行一系列操作(打開各種鏈接,訪問各種頁面)後,再關閉瀏覽器。這就叫一次會話。會話在百度百科的定義是是指一個終端用戶與交互系統進行通訊的過程。也就是說,會話技術是客戶端瀏覽器與服務器進行不斷交互的過程,在這個過程中,只要有一方不關閉,就可以說是在一次會話中。會話中包含多次請求和響應。
會話技術的方式有兩種:客戶端會話技術cookie與服務端會話技術session。

一、什麼是Session?

概念就是服務器端會話技術,在一次會話的多次請求間共享數據,將數據存在服務器端的對象(HttpSession)中,也就是說我們每次請求服務端,服務端就會在內存中爲我們開闢一個空間,這個空間就可以叫Session。這塊空間是跟瀏覽器息息相關的,在瀏覽器不關閉的情況下,我們可以正常訪問。如果我們新打開一個瀏覽器,這個瀏覽器就無法正常訪問了,要訪問也是重新在服務端內存中開闢空間,獲得對應這個瀏覽器的session。

獲取HttpSession對象:

HttpSession session = request.getSession()

對HttpSession對象的一些操作:

Object getAttribute(String name);
void setAttribute(String name, Object value);
void removeAttribute(String name);

此外,HttpSession還定義了一個invalidate的方法,該方法會強制會話過期,並且清空其保存的對象。默認情況下,HttpSession會在用戶不活動一段時間後自動過期。我們可以動過調用HttpSession的serMaxInactiveInterval來單獨的對某個HttpSession來設置其超時時間:

void setMaxInactiveInterval(int seconds);

如果傳入的參數爲0,則該HttpSession永不過期(這並不是一個好的設計方法,這麼設計的話該HttpSession所佔用的堆內存將永不釋放,直到應用重新加載或者Sevlet容器關閉)。

二、Session的一些細節

1、當客戶端關閉後,服務器不關閉,兩次獲取的session是否爲同一個?
答:默認情況下不是的,如果要期望客戶端關閉後session也能爲相同的,我們可以創建cookie,鍵爲JSESSIONID,設置最大存活時間,讓cookie持久化保存。(實際上就是將session以cookie的形式存起來了)

Cookie cookie = new Cooke("JSESSIONID", session.getId());
cookie.setMaxAge(60*60*24*30);
response.addCookie(cookie);

2、客戶端不關閉,服務器關閉後,兩次獲取的session是同一個嗎?
答:肯定也不是同一個,服務器關閉後,session對象隨即被銷燬,下次在啓動創建的時候,地址不是同一個,下次創建分配地址的時候,很難做到地址相同。如果我們要確保服務器關閉後原session還在,數據不流失,我們可以將session鈍化(即在服務器正常關閉前,將session對象序列化到硬盤上),然後在將session活化(在服務器啓動後,將session文件轉化爲內存中的session對象即可)。


3、session的失效時間?

  • 服務器關閉,session被銷燬。
  • 調用其invalidate()方法,自行銷燬。
  • session的默認失效時間爲30min,我們可以在tomcat下的web.xml中設置session-config來確保其最大存活時間。

4、我們如何知道這個session就對應的這個瀏覽器呢,怎麼保證瀏覽器不去訪問其他的session呢?
答:當我們訪問一個頁面的時候,服務端會給這個瀏覽器創建一個獨一的號碼,同時也給創建的session同樣的號碼,這樣我們用這個瀏覽器訪問該頁面的子頁面的時候,就會可以獲取到主頁面的session信息。這個號碼叫做jsessionID

三、Session的實現方式

第一種使用cookie的方式實現
如果瀏覽器支持的話,我們可以把sessionID放在cookie裏面。cookie有臨時的也有定時的。臨時的就是瀏覽器關閉然後cookie消失,正好符合session的理念。保存在cookie裏的jsessionID是獨一無二的。
第二種使用URL重寫的方式實現
如果瀏覽器不支持cookie,我們只能自己手動編程重寫URL來實現session。我們可以使用一個方法response.encodeURL()
該方法有兩個作用:一是轉碼(轉中文或者其他特殊字符的編碼),二是在URL後面加上jsessionID。
若想使程序永遠支持session,那就加上encodeURL,這樣即使別人禁用了cookie,我們也一樣可以使用session。

四、Session的特點以及與Cookie的對比

1、session是用於存儲一次會話的多次請求數據,它是存在服務器端的。
2、session可以存儲任意類型,任意大小的數據。
3、與cookie對比:session存儲數據在服務器端,而cookie在客戶端;session沒有數據大小限制,cookie有;session數據安全,而cookie相對不太安全。

五、Session跨域

什麼是session跨域?
Session跨域就是擯棄了系統提供的Session,而是用自定義的類似Session的機制來保存客戶端數據的一種解決方案。
如:通過設置cookie的domain來實現cookie的跨域傳遞。在cookie中傳遞一個自定義的session_id。這個session_id是客戶端的唯一標記,將這個標記作爲key,將客戶端需要保存的數據作爲value,在服務端進行保存,這種機制就是Session的跨域解決。
相關概念解釋:

  • 跨域:客戶端請求的時候,請求的服務器不是同一個IP、端口、域名、主機名的時候都稱爲跨域。
  • 域:一個完整的,有獨立訪問路徑的功能集合稱爲一個域。如:百度稱爲一個應用或系統。百度下有若干的域,如搜索,貼吧等。
  • 域信息:有時也稱爲多級域名。域的劃分:以IP、端口、域名、主機名爲標準進行劃分。不同的域有不同的cookie信息

解決方案:
1、session sticky:會話保存在單機上,保證會話請求落在同一臺服務器上。
採用源地址哈希法進行負載均衡(根據獲取客戶端的ip地址,通過哈希函數計算得到的一個數值,用該數值對服務器列表的大小進行取模運算,得到的結果便是客戶端要訪問服務器的序號),同一ip地址的客戶端,當後端服務器列表不變時,它每次都會映射到同一臺後端服務器進行訪問。

這種方法存在的問題是:如果一臺web服務器宕機或者重啓,那麼這臺機器上保存的會話數據都會丟失,會造成用戶之前的授權操作都需要再進行一次。
2、session replication:session複製,每一臺服務器上都保持一份相同的session(造成額外的存儲開銷和網絡開銷)
session複製,通過相關技術實現session複製,使得集羣中的各個服務器相互保存各自節點存儲的session數據。tomcat本身就可以實現session複製的功能。
這種方法存在的問題是:

  • 同步session數據會造成網絡開銷,隨着集羣規模越大,同步session帶來的帶寬影響也越大。
  • 每個節點需要保存集羣中所有結點的session數據,就需要比較大的內存來存儲。

3、session集中存儲:存儲在db、緩存服務器(redis)
4、使用cookie跨域共享

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