session技術

YING_XI發表於2020-11-02

一、session的概念及特點
  session概念:在計算機中,尤其是在網路應用中,稱為“會話控制”。Session 物件儲存特定使用者會話所需的屬性及配置資訊。說白了session就是一種可以維持伺服器端的資料儲存技術。session主要有以下的這些特點:session儲存的位置是在服務端session一般來說要配合cookie使用,如果使用者瀏覽器禁用了cookie,那麼只能使用URL重寫來實現session的儲存功能單純的使用session來儲存使用者回話資訊,那麼當使用者量較多時,session檔案數量會很多,會存在session查詢慢的問題本質上:session技術就是一種基於後端有別於資料庫的臨時儲存技術二、為什麼要使用session  我們目前使用的網際網路應用層協議基本上都是基於 HTTP 和 HTTPS 的,它們的本身是無狀態的, 只負責請求和響應。 我告訴伺服器我需要什麼,伺服器返回給我相應的資源。 如果沒有額外處理的話, 伺服器是不知道你是誰,更無法根據你是誰給你展現和你相關的內容了。HTTP 協議一開始被設計成這樣還是有一些歷史原因的,當時的網際網路多用於學術交流,只用於文章資訊的展現之類的事情,遠沒有現在這麼豐富多彩。所以在當時的背景下 HTTP 協議被設計成這樣其實也是很符合它的場景的。但隨著網際網路應用越來越廣泛,應用的形式也變得越來越多,我們的 Web 應用不只限於提供簡單的資訊展現了,還需要使用者能夠登入,可以在論壇發帖子,在購物網站買東西等等。 這就需要 HTTP 協議能夠記錄使用者的狀態。也就是我們現在熟悉的 Session 由來。三、session的工作原理使用者第一次請求伺服器時,伺服器端會生成一個sessionid伺服器端將生成的sessionid返回給客戶端,通過set-cookie客戶端收到sessionid會將它儲存在cookie中,當客戶端再次訪問服務端時會帶上這個sessionid當服務端再次接收到來自客戶端的請求時,會先去檢查是否存在sessionid,不存在就新建一個sessionid重複1,2的流程,如果存在就去遍歷服務端的session檔案,找到與這個sessionid相對應的檔案,檔案中的鍵值便是sessionid,值為當前使用者的一些資訊此後的請求都會交換這個 Session ID,進行有狀態的會話。四、session的生命週期Session何時生效:Sessinon在使用者訪問第一次訪問伺服器時建立,需要注意只有訪問JSP、Servlet等程式時才會建立Session,只訪問HTML、IMAGE等靜態資源並不會建立Session,可呼叫request.getSession(true)強制生成Session。Session何時失效:1.伺服器會把長時間沒有活動的Session從伺服器記憶體中清除,此時Session便失效。Tomcat中Session的預設失效時間為20分鐘。從session不活動的時候開始計算,如果session一直活動,session就總不會過期。從該Session未被訪問,開始計時; 一旦Session被訪問,計時清0;2.呼叫Session的invalidate方法HttpSession session = request.getSession();session.invalidate();//登出該request的所有session4.設定session的失效時間a)web.xml中30b)在程式中手動設定session.setMaxInactiveInterval(30 * 60);//設定單位為秒,設定為-1永不過期request.getSession().setMaxInactiveInterval(-1);//永不過期c)tomcat也可以修改session過期時間,在server.xml中定義context時採用如下定義:5.關閉瀏覽器,session就會失效五、session的效能瓶頸  另外一個要聊聊的就是 Session 資料的儲存。 通常情況下,如果你不明確的設定, 大多數 Web 框架會把 Session 資料存放到記憶體中。如果你的 Web 應用使用者量不大的話,這也不成問題。 但如果你的使用者數比較大的話,就可能發生一個事情 — 記憶體不夠用了。這很正常,記憶體容量是非常寶貴的,假設每個使用者的 Session 資料是 100K, 1萬個使用者就會大概佔用 1G 的儲存空間,如果你的 Session 資料清理機制也恰巧比較慢的話,記憶體非常容易被佔滿。這就需要你在設計比較大併發量的站點時,要考慮 Session 的儲存方式,比如把它們儲存到硬碟檔案系統中,或者資料庫中。 所以你在開發一個 Web 應用的時候,如果你的使用者量很大,你需要有這個意識。另外 Session 放到記憶體中還有一個弊端,如果你的 Web 伺服器發生重啟,那麼所有的 Session 狀態都會被情況,會在一定程度上影響使用者體驗。(引用自網路)

session與Httpsession是同一個東西嗎?
答:不是完全相同東西,有不同之處也有心愛相同之處。

一個session就是一系列某使用者和伺服器間的通訊。伺服器有能力分辨出不同的使用者。一個session的建立是從一個使用者向伺服器發第一個請求開始,而以使用者顯式結束或session超時為結束。
其工作原理是這樣的: 1.當一個使用者向伺服器傳送第一個請求時,伺服器為其建立一個session,併為此session建立一個標識號; 2.這個使用者隨後的所有請求都應包括這個標識號。伺服器會校對這個標識號以判斷請求屬於哪個session。 這種機制不使用IP作為標識,是因為很多機器是通過代理伺服器方式上網,沒法區分每一臺機器。 對於session標識號(sessionID),有兩種方式實現:cookies和URL重寫。 HttpSession的使用 我們來看看在API中對session是如何定義和操作的。 當需要為使用者端建立一個session時,servlet容器就建立了一個HttpSession物件。其中儲存了和本session相關的資訊。所以,在一個servlet中有多少個不同使用者連線,就會有多少個HttpSession物件。 使用的機理是: 1.從請求中提取HttpSession物件; 2.增加或刪除HttpSession中的屬性; 3.根據需要關閉HttpSession或使其失效。 在請求中有兩個過載的方法用來獲取HttpSession物件。 HttpSession getSession(boolean create)/getSession();作用是提取HttpSession物件,如果沒有自動建立。 獲取到HttpSession物件後,我們就需要使用HttpSession的某些方法去設定和更改某些引數了。如: void setAttribute(String name, Object value); Object getAttribute(String name); void removeAttribute(String name); 在javax.servlet.http包裡一共定義了四個session監聽器介面和與之關聯的兩個session事件。分別是: HttpSessionAttributeListener and HttpSessionBindingEvent; HttpSessionBindingListener and HttpSessionBindingEvent; HttpSessionListener and HttpSessionEvent; HttpSessionActivationListener and HttpSessionEvent. 他們的繼承關係是: 所有四個介面的父類是java.util.EventListener; HttpSessionEvent擴充套件java.util.EventObject; 而HttpSessionBindingEvent又擴充套件了HttpSessionEvent。 以下分別詳述: HttpSessionAttributeListener 當session中的屬性被新增,更改,刪除時得到通知。這個介面上節講過,主要看其它三個。 HttpSessionBindingListener 當一個實現了HttpSessionBindingListener的類被加入到HttpSession中(或從中移出)時,會產生HttpBindingEvent事件,而這些事件會被它本身接收到。 本介面定義了兩個方法: void valueBound(HttpSessionBindingEvent e); void valueUnbound(HttpSessionBindingEvent e); 當多個實現了HttpSessionBindingListener的類被加入到HttpSession中時,各類的方法只對本類感興趣,不會去理會其它類的加入。 即使是同一類的不同例項間,也是互不關心的(各掃門前雪)。 我們可以看到前兩個介面都對HttpSessionBindingEvent事件做出反應,但機理不同。 HttpSessionAttributeListener是在web.xml中登記的,servlet容器僅建立一個例項,來為任何在session中增加屬性的servlet服務。觸發事件的物件是所有可以轉換為Object的例項。 HttpSessionBindingListener不用在web.xml中登記,在每個servlet中用new建立例項,且僅對本例項向session中的加入(或移出)感興趣。觸發事件的物件僅僅是自己。 HttpSessionListener 對於session的建立和取消感興趣。需要在web.xml中登記。 共有兩個方法: void sessionCreated(HttpSessionEvent se); void sessionDestroyed(HttpSessionEvent se); 使用它我們可以容易的建立一個類來對session計數。 也許我們會簡單的考慮使用sessionDestroyed方法來在session結束後做一些清理工作。但是,請注意,當這個方法被呼叫的時候,session已經結束了,你不能從中提取到任何資訊了。因此,我們要另闢蹊徑。 一種通常採用的方法是使用HttpSessionBindingListener介面。在session建立時增加一個屬性,而在session結束前最後一件事將這個屬性刪除,這樣就會觸發valueUnbound方法,所有對session的清理工作可以在這個方法中實現。 HttpSessionActivationListener 當session在分散式環境中跨JVM時,實現該介面的物件得到通知。共兩個方法: void sessionDidActivate(HttpSessionEvent se); void sessionWillPassivate(HttpSessionEvent se);

1、HTTP協議本身是“連線-請求-應答-關閉連線”模式的,是一種無狀態協議(HTTP只是一個傳輸協議);
2、Cookie規範是為了給HTTP增加狀態跟蹤用的(如果要精確把握,建議仔細閱讀一下相關的RFC),但不是唯一的手段;
3、所謂Session,指的是客戶端和服務端之間的一段互動過程的狀態資訊(資料);這個狀態如何界定,生命期有多長,這是應用本身的事情;
4、由於B/S計算模型中計算是在伺服器端完成的,客戶端只有簡單的顯示邏輯,所以,Session資料對客戶端應該是透明的不可理解的並且應該受控於服務端;Session資料要麼儲存到服務端(HttpSession),要麼在客戶端和服務端之間傳遞(Cookie或url rewritting或Hidden input);
5、由於HTTP本身的無狀態性,服務端無法知道客戶端相繼發來的請求是來自一個客戶的,所以,當使用服務端HttpSession儲存會話資料的時候客戶端的每個請求都應該包含一個session的標識(sid, jsessionid 等等)來告訴服務端;
6、會話資料儲存在服務端(如HttpSession)的好處是減少了HTTP請求的長度,提高了網路傳輸效率;客戶端session資訊儲存則相反;
7、客戶端Session儲存只有一個辦法:cookie(url rewritting和hidden input因為無法做到持久化,不算,只能作為交換session id的方式,即a method of session tracking),而服務端做法大致也是一個道理:容器有個session管理器(如tomcat的org.apache.catalina.session包裡面的類),提供session的生命週期和持久化管理並提供訪問session資料的api;
8、使用服務端還是客戶端session儲存要看應用的實際情況的。一般來說不要求使用者註冊登入的公共服務系統(如google)採用cookie做客戶端session儲存(如google的使用者偏好設定),而有使用者管理的系統則使用服務端儲存。原因很顯然:無需使用者登入的系統唯一能夠標識使用者的就是使用者的電腦,換一臺機器就不知道誰是誰了,服務端session儲存根本不管用;而有使用者管理的系統則可以通過使用者id來管理使用者個人資料,從而提供任意複雜的個性化服務;
9、客戶端和服務端的session儲存在效能、安全性、跨站能力、程式設計方便性等方面都有一定的區別,而且優劣並非絕對(譬如TheServerSide號稱不使用HttpSession,所以效能好,這很顯然:一個具有上億的訪問使用者的系統,要在服務端資料庫中檢索出使用者的偏好資訊顯然是低效的,Session管理器不管用什麼資料結構和演算法都要耗費大量記憶體和CPU時間;而用cookie,則根本不用檢索和維護session資料,伺服器可以做成無狀態的,當然高效);
10、所謂的“會話cookie”簡單的說就是沒有明確指明有效期的cookie,僅在瀏覽器當前程式生命期內有效,可以被後繼的Set-Cookie操作清除掉

相關文章