1、session的本質
http協議是無狀態的,即你連續訪問某個網頁100次和訪問1次對服務器來講是沒有區別對待的,由於它記不住你。
那麼,在一些場合,確實須要服務器記住當前用戶怎麼辦?好比用戶登陸郵箱後,接下來要收郵件、寫郵件,總不能每次操做都讓用戶輸入用戶名和密碼吧,爲了解決這個問題,session的方案就被提了出來,事實上它並非什麼新技術,並且也不能脫離http協議以及任何現有的web技術。
原理很簡單,假設你訪問網頁時就像逛澡堂,第一次進去你是沒有鑰匙的,這個時候你交了錢服務檯就分配一把鑰匙給你,你走到哪裏都要帶上,由於這是你身份的惟一標識,接下來你用這把鑰匙能夠去打開一個專有的儲物櫃存儲你的衣物,游完泳,你再用鑰匙去打開櫃子拿出衣物,最後離開游泳池時,把鑰匙歸還,你的此次游泳的過程就是一次session,或者叫作會話,在這個例子中,鑰匙就是session的key,而儲物櫃能夠理解爲存儲用戶會話信息的介質。
那麼在web server中如何實現session呢?想必看了上面的例子你會很容易理解,主要是解決兩個問題,一個是鑰匙的問題,一個是存儲用戶信息的問題。對於第一個問題,即什麼東西可讓你每次請求都會自動帶到服務器呢?若是你比較瞭解http協議,那麼答案一目瞭然,就是cookie,若是你想爲用戶創建一次會話,能夠在用戶受權成功時給他一個cookie,叫作會話id,它固然是惟一的,好比php就會爲創建會話的用戶默認set一個名爲phpsessid,值看起來爲一個隨機字符串的cookie,若是下次發現用戶帶了這個cookie,服務器就知道,哎呀,剛剛這位顧客來了。
剩下的是解決第二個問題,即如何存儲用戶的信息,服務器知道會話id爲abc的用戶來了,那abc想存儲本身的私人信息,好比購物車信息,如何處理?這個時候能夠用內存、也能夠用文件,也能夠用數據庫了,但有個要求是,數據須要用用戶的會話id便可取到,好比php就默認會把會話id爲abc的用戶會話數據存儲到/tmp/phpsess_abc的文件裏面,每次讀取都要反序列化程序能夠理解的數據,寫的時候又須要序列化爲持久的數據格式。
較好理解的描述:
session被用於表示一個持續的鏈接狀態,在網站訪問中通常指代客戶端瀏覽器的進程從開啓到結束的過程。session其實就是網站分析的訪問(visits)度量,表示一個訪問的過程。
session的常見實現形式是會話cookie(session cookie),即未設置過時時間的cookie,這個cookie的默認生命週期爲瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。實現機制是當用戶發起一個請求的時候,服務器會檢查該請求中是否包含sessionid,若是未包含,則系統會創造一個名爲JSESSIONID的輸出 cookie返回給瀏覽器(只放入內存,並不存在硬盤中),並將其以HashTable的形式寫到服務器的內存裏面;當已經包含sessionid是,服務端會檢查找到與該session相匹配的信息,若是存在則直接使用該sessionid,若不存在則從新生成新的 session。這裏須要注意的是session始終是有服務端建立的,並不是瀏覽器本身生成的。 可是瀏覽器的cookie被禁止後session就須要用get方法的URL重寫的機制或使用POST方法提交隱藏表單的形式來實現。
2、如何實現session的共享?
首先咱們應該明白,爲何要實現共享,若是你的網站是存放在一個機器上,那麼是不存在這個問題的,由於會話數據就在這臺機器,可是若是你使用了負載均衡把請求分發到不一樣的機器呢?這個時候會話id在客戶端是沒有問題的,可是若是用戶的兩次請求到了兩臺不一樣的機器,而它的session數據可能存在其中一臺機器,這個時候就會出現取不到session數據的狀況,因而session的共享就成了一個問題。
1.各類web框架早已考慮到這個問題,好比asp.net,是支持經過配置文件修改session的存儲介質爲sql server的,全部機器的會話數據都從同一個數據庫讀,就不會存在不一致的問題;
2.以cookie加密的方式保存在客戶端.優勢是減輕服務器端的壓力,缺點是受到cookie的大小限制,可能佔用必定帶寬,由於每次請求會在頭部附帶必定大小的cookie信息,另外這種方式在用戶禁止使用cookie的狀況下無效.
3.服務器間同步。定時同步各個服務器的session信息,此方法可能有必定延時,用戶體驗也不是很好。
4.php支持把會話數據存儲到某臺memcache服務器,你也能夠手工把session文件存放的目錄改成nfs網絡文件系統,從而實現文件的跨機器共享。
還有一個簡單的辦法能夠用於會話信息不會頻繁變動的狀況,在機器a設置用戶會話的時候,把會話數據post到機器b的一個cgi,機器b的cgi把會話數據存下來,這樣機器a和b都會有同一份session數據的拷貝。php