一、前言
之前的文章已經介紹了Cookie可以讓服務端程式跟蹤每個用戶端的通路,但是每次用戶端的通路都必須傳回這些Cookie,如果Cookie很多,這無形地增加了用戶端與服務端的資料傳輸量,為了解決這個問題,Session就出現了。
二、概念
Session機制是一種伺服器端的機制,伺服器使用一種類似于散清單的結構(也可能就是使用散清單)來儲存資訊。
相比于儲存在用戶端的Cookie,Session将使用者互動資訊儲存在了伺服器端,使得同一個用戶端每次和服務端互動時,不需要每次都傳回所有的Cookie值,而是隻要傳回一個ID,這個ID是用戶端第一次通路伺服器的時候生成的,而且每個用戶端是唯一的。這樣就實作了一個ID就能在伺服器取得所有的使用者互動資訊。
三、Session的工作流程
1、session的建立:session是在用戶端與伺服器互動的過程中,由伺服器建立的,并且會傳回一個session的Id給用戶端,一個會話隻能有一個session對象;
2、在此後的互動過程中,用戶端在請求中帶上這個ID;
3、伺服器可根據此Session ID擷取到對應的儲存在伺服器記憶體中的session内容,以便于識别使用者并提取使用者資訊。

(圖檔來自于http://blog.csdn.net/happyguys12345/article/details/74910595)
注:一般情況下用戶端session的ID都是通過Cookie的方式與伺服器互動的,對于用戶端禁用了Cookie的情況,可以通過在請求的Url中帶上這個Session ID達到使用Session的目的。(也有一些在頁面表單隐藏字段添加session id的,但是需要請求有送出表單的行為時才可實作session互動)
四、Session的生命周期
Session在以下情況會被删除失效:
1、Session逾時:逾時指的是連續一定時間伺服器沒有收到該Session所對應用戶端的請求,并且這個時間超過了伺服器設定的Session逾時的最大時間;
2、程式調用方法主動銷毀session;
3、伺服器關閉或服務停止。
五、Session的作用範圍
一般來說,每次請求不同的域都會新建立一個session:
對于多标簽的浏覽器來說,在一個浏覽器視窗中,多個标簽同時通路一個頁面,session是一個。
對于多個浏覽器視窗之間,同時或者相隔很短時間通路一個頁面,session是多個的,和浏覽器的程序有關。
對于一個同一個浏覽器視窗,直接錄入url通路同一應用的不同資源,session是一樣的。
比如PHP寫的服務端,每次打開同一個域名網站的頁面都是一樣的session,在多個标簽裡面也是一樣;但在多個視窗就是不一樣的(可能有些浏覽器不是),通路不同的域也是不一樣的,除非做了Session同步機制。
六、PHP操作Session方法
php的session預設情況下是使用用戶端Cookie。當用戶端的Cookie被禁用時,會自動通過URL的Query_String傳遞。
(必須在php.ini中做以下配置:
session.use_trans_sid=1 //是否開啟url傳遞PHPSESSION ID
session.use_only_cookies=0 //是否隻允許使用Cookie 傳遞PHPSESSION ID
session.use_cookies=1 //是否開啟Cookie傳遞PHPSESSION ID
需要保證伺服器有session.save_path路徑的必要權限。
)
1、session建立:在PHP中建立Session是用session_start()方法,同Cookie一樣,必須将這個函數置于最先,而且在它之前不能有任何輸出,否則會報錯。同理可以用之前文章介紹過的輸出緩沖的方法避免。
2、清空session:session_destroy()方法,此函數沒有參數,且傳回值均為true。
3、擷取Session:PHP中擷取session用$_SESSION[$name]變量擷取,該變量在接收到請求時會自動擷取到請求裡面帶有的Session id,并以數組的格式提取儲存着該ID所帶有的在伺服器端的session資料(session的資料也是采用Key/Value的格式,value格式可支援多種);
4、Session值的修改更新:
可直接通過給$_SESSION[$name]變量指派的格式更新session值,并且可以立即生效。
七、實際應用中session存在的問題與不足
1、為了彌補http協定的無狀态的特點,服務端會占用一定的記憶體和cpu用來存儲和處理session計算的開銷,在大流量大通路量的網站中,這會導緻大量的占用伺服器記憶體和計算速度;
2、有些高通路量的站點,需要部署多個伺服器,多台伺服器對外提供的服務是等價的,這樣可以減少每台伺服器的壓力,但是同一個使用者的多次請求可能會通路到多台伺服器,每台伺服器的同一個Session ID必須對應同一個Session内容,這就需要Session在多台伺服器之間實作同步;
3、每個使用者在每台伺服器之間的Session ID都應該辨別使用者自己,是以多個伺服器之間的不同session必須是互相獨立的;
八、Session同步的方案
多台伺服器之間必須共享session,是以session同步到各個伺服器的方式就是把session儲存起來,讓各個伺服器都可以通路到這個儲存的地方;可以儲存到檔案、資料庫、記憶體等,由于檔案和資料庫是IO讀寫,效率比較低,是以目前最好的方案是将Session儲存在記憶體中。
很多大型企業采用的方案是在單獨的緩存伺服器如memcache或者Redis裡面儲存Session,同步到各個伺服器這種方案。
當然Session還有很多值得我們學習和探讨的問題,例如:
1、Session 存儲的多元化;
2、Session 配置的動态修改;
3、Session 加密 key 的定期修改。