1. 程式人生 > >Session 簡介以及實現與工作原理

Session 簡介以及實現與工作原理

Session 是存放在伺服器端的,類似於Session結構來存放使用者資料,當瀏覽器 第一次傳送請求時,伺服器自動生成了一個Session和一個Session ID用來唯一標識這個Session,並將其通過響應傳送到瀏覽器。當瀏覽器第二次傳送請求,會將前一次伺服器響應中的Session ID放在請求中一併傳送到伺服器上,伺服器從請求中提取出Session ID,並和儲存的所有Session ID進行對比,找到這個使用者對應的Session。

什麼是Session

Session 是一種Web會話中的常用狀態之一

在WEB開發中,伺服器可以為每個使用者瀏覽器建立一個會話物件(session物件),注意:一個瀏覽器獨佔一個session物件(預設情況下)。

因此,在需要儲存使用者資料時,伺服器程式可以把使用者資料寫到使用者瀏覽器獨佔的session中,當用戶使用瀏覽器訪問其它程式時,其它程式可以從使用者的session中取出該使用者的資料,為使用者服務。

Session 是一個鍵值對(伺服器)

一般情況下,伺服器會在一定時間內(預設30分鐘)儲存這個 Session,過了時間限制,就會銷燬這個Session。在銷燬之前,程式設計師可以將使用者的一些資料以Key和Value的形式暫時存放在這個 Session中。當然,也有使用資料庫將這個Session序列化後儲存起來的,這樣的好處是沒了時間的限制,壞處是隨著時間的增加,這個資料 庫會急速膨脹,特別是訪問量增加的時候。一般還是採取前一種方式,以減輕伺服器壓力。

Session 提供了一種把資訊儲存在伺服器記憶體中的方式

Session機制是一種伺服器端的機制,伺服器使用一種類似於散列表的結構(也可能就是使用散列表)來儲存資訊。 他能儲存任何資料型別,包含自定義物件。在整個會話過程中,只要SessionID的cookie不丟失,都會儲存Session資訊的。

Session不能跨程序訪問,只能由該會話的使用者訪問

應為提取Session資料的id標識是以Cookie的方式儲存到訪問者瀏覽器的快取裡的。

當會話終止,或過期時,伺服器就清除Session物件

Session常用於儲存登入使用者的ID

Session儲存的資料是跨頁面全域性型的

Session實現與工作原理

瀏覽器和伺服器採用http無狀態的通訊,為了保持客戶端的狀態,使用session來達到這個目的。在session機制中,也採用了這樣的一個唯一的session_id來標示不同的使用者,不同的是:瀏覽器每次請求都會帶上由伺服器為它生成的session_id

簡單介紹一下流程:

當客戶端訪問伺服器時,伺服器根據需求設定session,將會話資訊儲存在伺服器上,同時將標示session的session_id傳遞給客戶端瀏覽器,瀏覽器將這個session_id儲存在記憶體中(還有其他的儲存方式,例如寫在url中),我們稱之為無過期時間的cookie。瀏覽器關閉後,這個cookie就清掉了,它不會存在使用者的cookie臨時檔案。

以後瀏覽器每次請求都會額外加上這個引數值,再伺服器根據這個session_id,就能取得客戶端的資料狀態。

如果客戶端瀏覽器意外關閉,伺服器儲存的session資料不是立即釋放,此時資料還會存在,只要我們知道那個session_id,就可以繼續通過請求獲得此session的資訊;但是這個時候後臺的session還存在,但是session的儲存有一個過期時間,一旦超過規定時間沒有客戶端請求時,他就會清除這個session。

下面介紹一下session的儲存機制,預設的session是儲存在files中,即以檔案的方式儲存session資料。在php中主要根據php.ini的配置session.save_handler來選擇儲存session的方式。

這裡順便說明一下,如果要做伺服器的lvs,即多臺server的話,我們一般使用memcached的方式session,否則會導致一些請求找不到session。

一個簡單的memcache配置:

session.save_handler = memcache

session.save_path = "tcp://10.28.41.84:10001"
當然如果一定要使用files檔案快取,我們可以將檔案作nfs,將所有的儲存session檔案定位到一個地方。
剛才講返回給使用者的session-id最終儲存在記憶體中,這裡我們也可以設定引數將其儲存在使用者的url中。

Session的客戶端實現形式(即Session ID的儲存方法)

一般瀏覽器提供了兩種方式來儲存,還有一種是程式設計師使用html隱藏域的方式自定義實現:

[1] 使用Cookie來儲存,這是最常見的方法,本文“記住我的登入狀態”功能的實現正式基於這種方式的。伺服器通過設定Cookie的方式將Session ID傳送到瀏覽器。如果我們不設定這個過期時間,那麼這個Cookie將不存放在硬碟上,當瀏覽器關閉的時候,Cookie就消失了,這個Session ID就丟失了。如果我們設定這個時間為若干天之後,那麼這個Cookie會儲存在客戶端硬碟中,即使瀏覽器關閉,這個值仍然存在,下次訪問相應網站時,同 樣會發送到伺服器上。

[2] 使用URL附加資訊的方式,也就是像我們經常看到JSP網站會有aaa.jsp?JSESSIONID=*一樣的。這種方式和第一種方式裡面不設定Cookie過期時間是一樣的。

[3] 第三種方式是在頁面表單裡面增加隱藏域,這種方式實際上和第二種方式一樣,只不過前者通過GET方式傳送資料,後者使用POST方式傳送資料。但是明顯後者比較麻煩。

session物件的建立和銷燬時機

session物件的建立時機:

在程式中第一次呼叫request.getSession()方法時就會建立一個新的Session,可以用isNew()方法來判斷Session是不是新建立的。

session物件的銷燬時機:

session物件預設30分鐘沒有使用,則伺服器會自動銷燬session,在web.xml檔案中可以手工配置session的失效時間。

Q&A

使用者開一個瀏覽器訪問一個網站,伺服器是不是針對這次會話建立一個session?

不是的。session的建立時機是在程式中第一次去執行request.getSession();這個程式碼,伺服器才會為你建立session。 

關閉瀏覽器,會話結束,session是不是就銷燬了呢? 

不是的。session是30分鐘沒人用了才會死,伺服器會自動摧毀session。