1. 程式人生 > >session機制詳解以及session的相關應用

session機制詳解以及session的相關應用

sessionweb開發裡一個重要的概念,在大多數web應用裡session都是被當做現成的東西,拿來就直接用,但是一些複雜的web應用裡能拿來用的session已經滿足不了實際的需求,當碰到這樣的情況時候我們需要更加深入的理解session的機制,本文將梳理下session的相關知識,為設計可替代web容器自帶的session機制打個基礎。

1.1 session的概念

在計算機專業術語裡:session是指一個終端使用者與互動系統進行通訊的時間間隔,通常指從註冊入系統到登出系統之間所經過的時間以及如果需要的話,可能還有一定操作空間。

具體到web應用裡的session

,大家都做過web開發,這裡我就先不提出websession的定義,先和大夥講下和session相關的技術背景。

早期的web應用或者說早期的網站都是一種處理靜態資源的網站,功能主要是檢視文件,看看圖片,而現在的web應用和早期的差別已經很大,網際網路的網站更準確的定義應該是網際網路軟體即網站就是軟體,網站所代表的軟體和早期軟體的定義是不一樣的,早期的軟體都是在單機環境下執行,而網際網路的普及讓軟體和網路技術融合在一起,這就要求網站所代表的軟體應該要有一個對事務處理的記憶功能,事務處理的記憶功能就是我們常說的要有狀態。而實現web應用技術的核心http協議是一個無狀態的協議,http這種設計也許是歷史遺留問題,也許無狀態的

http是最簡單也是最有效的通訊方式,但是當網站成為軟體後,狀態的保持就是一個很重要的功能。

因此在web應用開發裡就出現了保持http連結狀態的技術:一個是cookie技術,另一種是session技術。

cookie技術是客戶端的解決方案(當然隨著html5的出現,比cookie更為強勁和安全的技術出現了,但是鑑於html5的普及度不夠,就不做本文討論的內容了),Cookie就是由伺服器發給客戶端的特殊資訊,而這些資訊以文字檔案的方式存放在客戶端,然後客戶端每次向伺服器傳送請求的時候都會帶上這些特殊的資訊。讓我們說得更具體一些:當用戶使用瀏覽器訪問一個支援Cookie的網站的時候,使用者會提供包括使用者名稱在內的個人資訊並且提交至伺服器;接著,伺服器在向客戶端回傳相應的超文字的同時也會發回這些個人資訊,當然這些資訊並不是存放在

HTTP響應體(Response Body)中的,而是存放於HTTP響應頭(Response Header);當客戶端瀏覽器接收到來自伺服器的響應之後,瀏覽器會將這些資訊存放在一個統一的位置,對於Windows作業系統而言,我們可以從: [系統盤]:\Documents and Settings\[使用者名稱]\Cookies目錄中找到儲存的Cookie;自此,客戶端再向伺服器傳送請求的時候,都會把相應的Cookie再次發回至伺服器。而這次,Cookie資訊則存放在HTTP請求頭(Request Header)了。有了Cookie這樣的技術實現,伺服器在接收到來自客戶端瀏覽器的請求之後,就能夠通過分析存放於請求頭的Cookie得到客戶端特有的資訊,從而動態生成與該客戶端相對應的內容。通常,我們可以從很多網站的登入介面中看到“請記住我”這樣的選項,如果你勾選了它之後再登入,那麼在下一次訪問該網站的時候就不需要進行重複而繁瑣的登入動作了,而這個功能就是通過Cookie實現的。

session技術則是服務端的解決方案,它是通過伺服器來保持狀態的。由於Session這個詞彙包含的語義很多,因此需要在這裡明確一下 Session的含義。首先,我們通常都會把Session翻譯成會話,因此我們可以把客戶端瀏覽器與伺服器之間一系列互動的動作稱為一個 Session。從這個語義出發,我們會提到Session持續的時間,會提到在Session過程中進行了什麼操作等等;其次,Session指的是伺服器端為客戶端所開闢的儲存空間,在其中儲存的資訊就是用於保持狀態。從這個語義出發,我們則會提到往Session中存放什麼內容,如何根據鍵值從 Session中獲取匹配的內容等。要使用Session,第一步當然是建立Session了。那麼Session在何時建立呢?當然還是在伺服器端程式執行的過程中建立的,不同語言實現的應用程式有不同建立Session的方法,而在Java中是通過呼叫HttpServletRequestgetSession方法(使用true作為引數)建立的。在建立了Session的同時,伺服器會為該Session生成唯一的Session id,而這個Session id在隨後的請求中會被用來重新獲得已經建立的Session;在Session被建立之後,就可以呼叫Session相關的方法往Session中增加內容了,而這些內容只會儲存在伺服器中,發到客戶端的只有Session id;當客戶端再次傳送請求的時候,會將這個Session id帶上,伺服器接受到請求之後就會依據Session id找到相應的Session,從而再次使用之。正式這樣一個過程,使用者的狀態也就得以保持了。

由此我們可以得出,session是解決http協議無狀態問題的服務端解決方案,它能讓客戶端和服務端一系列互動動作變成一個完整的事務,能使網站變成一個真正意義上的軟體。

1.2 cookiesession的關係

cookiesession的方案雖然分別屬於客戶端和服務端,但是服務端的session的實現對客戶端的cookie有依賴關係的,上面我講到服務端執行session機制時候會生成sessionid值,這個id值會發送給客戶端,客戶端每次請求都會把這個id值放到http請求的頭部發送給服務端,而這個id值在客戶端會儲存下來,儲存的容器就是cookie,因此當我們完全禁掉瀏覽器的cookie的時候,服務端的session也會不能正常使用(注意:有些資料說ASP解決這個問題,當瀏覽器的cookie被禁掉,服務端的session任然可以正常使用,ASP我沒試驗過,但是對於網路上很多用phpjsp編寫的網站,我發現禁掉cookie,網站的session都無法正常的訪問)

1.3 session實現的原理

javaweb容器都實現了session機制,實現的邏輯思想都是一致的,但是具體方案可能會存在一定差異,這裡我以tomcat容器為例,探討下session實現的機制。

下圖是tomcat原始碼裡session實現:

實現包的路徑是:org.apache.catalina.sessiontomcat對外提供session呼叫的介面不在這個實現包裡,對外介面是在包javax.servlet.http下的HttpSession,而實現包裡的StandardSessiontomcat提供的標準實現,當然對外tomcat不希望使用者直接操作StandardSession,而是提供了一個StandardSessionFacade類,tomcat容器裡具體操作session的元件是servlet,而servlet操作session是通過StandardSessionFacade進行的,這樣就可以防止程式設計師直接操作StandardSession所帶來的安全問題。(StandardSessionFacade使用了設計模式裡的Façade(外觀)模式,外觀模式能讓不同邏輯層的元件進行解耦)

實現類裡有Manager的類是用來管理session的工具類,它負責建立和銷燬session物件,其中ManagerBase是所有session管理工具類的基類,它是一個抽象類,所有具體實現session管理功能的類都要繼承這個類,該類有一個受保護的方法,該方法就是建立sessionId值的方法(tomcatsessionid值生成的機制是一個隨機數加時間加上jvmid值,jvmid值會根據伺服器的硬體資訊計算得來,因此不同jvmid值都是唯一的),StandardManager類是tomcat容器裡預設的session管理實現類,它會將session的資訊儲存到web容器所在伺服器的記憶體裡。PersistentManagerBase也是繼承ManagerBase類,它是所有持久化儲存session資訊的基類,PersistentManager繼承了PersistentManagerBase,但是這個類只是多了一個靜態變數和一個getName方法,目前看來意義不大,對於持久化儲存sessiontomcat還提供了StoreBase的抽象類,它是所有持久化儲存session的基類,另外tomcat還給出了檔案儲存FileStore和資料儲存JDBCStore兩個實現。

1.4 在實際運用中session所帶來的問題

由上面所描述的session實現機制,我們會發現,為了彌補http協議的無狀態的特點,服務端會佔用一定的記憶體和cpu用來儲存和處理session計算的開銷,這也就是tomcat這個的web容器的併發連線那麼低(tomcat官方文件裡預設的連線數是200)原因之一。因此很多java語言編寫的網站,在生產環境裡web容器之前會加一個靜態資源伺服器,例如:apache伺服器或nginx伺服器,靜態資源伺服器沒有解決http無狀態問題的功能,因此部署靜態資源的伺服器也就不會讓出記憶體或cpu計算資源專門去處理像session這樣的功能,這些記憶體和cpu資源可以更有效的處理每個http請求,因此靜態資源伺服器的併發連線數更高,所以我們可以讓那些沒有狀態保持要求的請求直接在靜態伺服器裡處理,而要進行狀態保持的請求則在java的web容器裡進行處理,這樣能更好的提升網站的效率。

當下的網際網路網站為了提高網站安全性和併發量,服務端的部署的伺服器的數量往往是大於或等於兩臺,多臺伺服器對外提供的服務是等價的,但是不同的伺服器上面肯定會有不同的web容器,由上面的講述我們知道session的實現機制都是web容器裡內部機制,這就導致一個web容器裡所生成的sessionid值是不同的,因此當一個請求到了A伺服器,瀏覽器得到響應後,客戶端存下的是A伺服器上所生成的sessionid,當在另一個請求分發到了B伺服器,B伺服器上的web容器是不能識別這個sessionid值,更不會有這個sessionID所對應記錄下來的資訊,這個時候就需要兩個不同web容器之間進行session的同步。Tomcat容器有一個官方的解決方案就是使用apache+tomcat+mod_jk方案,當一個web容器裡session的資訊發生變化後,該web容器會向另一個web容器進行廣播,另一個web收到廣播後將session資訊同步到自己的容器裡,這個過程是十分消耗系統資源,當訪問量增加會嚴重影響到網站的效率和穩定性。

我現在所做的網站裡有一個解決方案,當用戶請求網站的時候會先將請求傳送給硬體的負載均衡裝置,該裝置可以截獲客戶端傳送過來的sessionid值,然後我們根據這個id值找到產生這個session的伺服器,將請求直接傳送給這臺伺服器。這種解決方案看起來解決了session共享問題,其實結果是將集群系統最終變回了單點系統,如果處理請求的web容器掛掉了,那麼使用者的相關會話操作也就廢掉了。此外,這種做法也干擾了負載均衡伺服器的負載均衡的計算,讓請求的分發並不是公平的。

  一般大型互聯公司的網站都是有一個個獨立的頻道所組成的,例如我們常用的百度,會有百度搜索,百度音樂,百度百科等等,我相信他們不會把這些不同頻道都給一個開發團隊完成,應該每個頻道都是一個獨立開發團隊,因為每個頻道的應用的都是獨立的web應用,那麼就存在一個跨站點的session同步的問題,跨站點的登入可以使用單點登入的(SSO)的解決方案,但是不管什麼解決方案,跨站點的session共享任然是逃避不了的問題。

1.5 解決session相關問題的技術方案

由上所述,session一共有兩個問題需要解決:

1) session的儲存應該獨立於web容器,也要獨立於部署web容器的伺服器;

2)如何進行高效的session同步。

在講到解決這些問題之前,我們首先要考慮下session如何儲存才是高效,是存在記憶體、檔案還是資料庫了?檔案和資料庫的儲存方式都是將session的資料固化到硬碟上,操作硬碟的方式就是IOIO操作的效率是遠遠低於操作記憶體的資料,因此檔案和資料庫儲存方式是不可取的,所以將session資料儲存到記憶體是最佳的選擇。因此最好的解決方案就是使用分散式快取技術,例如:memcachedredis,將session資訊的儲存獨立出來也是解決session同步問題的方法。

Tomcatsession同步也有使用memcache的解決方案,大家可以參加下面的文章:

但是該方案只是解決了同步問題,session機制任然和web容器緊耦合,我們需要一個高效、可擴充套件的解決方案,那麼我們就應該不是簡單的把session獨立出來儲存而是設計一個完全獨立的session機制,它既能給每個web應用提供session的功能又可以實現session同步,下面是一篇用zookeeper實現的分散式session方案:

好了寫完了,今天只是簡單剖析下session機制,以後有機會我拿出一套最好的獨立session設計機制方案來的。

相關推薦

session機制以及session相關應用

session是web開發裡一個重要的概念,在大多數web應用裡session都是被當做現成的東西,拿來就直接用,但是一些複雜的web應用裡能拿來用的session已經滿足不了實際的需求,當碰到這樣的情況時候我們需要更加深入的理解session的機制,本文將梳理下session的相關知識,為設計可替代web容

Cookie/Session機制

order 隱藏對象 tro 這就是 緩存 cat 時域 共享 創建 會話(Session)跟蹤是Web程序中常用的技術,用來跟蹤用戶的整個會話。常用的會話跟蹤技術是Cookie與Session。Cookie通過在客戶端記錄信息確定用戶身份,Session通過在服務器端記錄

Session機制

ref:http://justsee.iteye.com/blog/1570652 雖然session機制在web應用程式中被採用已經很長時間了,但是仍然有很多人不清楚session機制的本質,以至不能正確的應用這一技術。本文將詳細討論session的工作機制並且對在J

Cookie/Session機制(講解的確實很不錯,分享給大家)

會話(Session)跟蹤是Web程式中常用的技術,用來跟蹤使用者的整個會話。常用的會話跟蹤技術是Cookie與Session。Cookie通過在客戶端記錄資訊確定使用者身份,Session通過在伺服器端記錄資訊確定使用者身份。 本章將系統地講述Cookie與S

如何區分不同使用者——Cookie/Session機制

會話(Session)跟蹤是Web程式中常用的技術,用來跟蹤使用者的整個會話。常用的會話跟蹤技術是Cookie與Session。Cookie通過在客戶端記錄資訊確定使用者身份,Session通過在伺服器端記錄資訊確定使用者身份。 本章將系統地講述Cookie與Session

[js點滴]JavaScript之Cookie/Session機制01

一 基本概念 會話(Session)跟蹤是Web程式中常用的技術,用來跟蹤使用者的整個會話。 常用的會話跟蹤技術是Cookie與Session。 1).Cookie通過在客戶端記錄資訊確定使用者身份 2).Session通過在伺服器端記錄資訊確定使

Java-異常機制以及開發時異常設計的原則要求

異常處理的合理性完整性體現了一門語言是否成熟。而Java作為目前最流行的開發語言之一,固然具有一個完善的異常處理機制。本文將對異常處理機制來一次大的總結,後面講解一些原則性問題、開發技巧以及經常遇到的異常。 文章結構:1.異常機制樹的講解; 2.異常處理

【l轉】php中session過期時間設定及回收機制

php中session過期時間設定及回收機制詳解: 修改php中的session過期時間可以修改php配置檔案php.ini中的session.gc_maxlifetime即可。 當php每發出一次請求時,會有1/100的概率(預設值)觸發"session回收"。如果"session回收"發生,那就會檢查

Cookie與 Session使用

method IT OS tro 創建 main 網站 strong see 1、Cookie和Session簡介與區別 在非常多時候,我們需要跟蹤瀏覽者在整個網站的活動,對他們身份進行自動或半自動的識別(也就是平時常說的網站登陸之類的功能),這時候,我們常采用Cooki

flask基礎之session原理(十)

前言 flask_session是flask框架實現session功能的一個外掛,用來替代flask自帶的session實現機制,flask預設的session資訊儲存在cookie中,不夠安全和靈活。 flask的session機制 session是用來幹什麼的呢?由於http協議是一個無狀態的協議,

CentOS 7安裝MariaDB 10以及相關配置

show utf8 內容 操作 4.0 ant star emctl baseurl CentOS 7安裝MariaDB 10詳解以及相關配置 第一步:添加 MariaDB yum 倉庫 首先在CentOS操作系統中/etc/yum.repos.d/目錄下添加 Mari

ActiveMQ訊息傳送機制以及ACK機制

AcitveMQ是作為一種訊息儲存和分發元件,涉及到client與broker端資料互動的方方面面,它不僅要擔保訊息的儲存安全性,還要提供額外的手段來確保訊息的分發是可靠的。   一. ActiveMQ訊息傳送機制     Producer客戶端使用來發送訊息的, Cons

Boost.ASIO原始碼:service_registry::use_service()以及相關type_traits解析

這都是神仙寫的程式碼吧 沒什麼,這個標題只是忍不住表達一下對ASIO的驚歎。 曾經看《STL原始碼剖析》對裡面的type_traits的設計驚為天人,沒想到看ASIO庫的時候又看到了同樣的設計模式,雖然對於C++功底還不深的我來說看起來十分的費勁,但我還是決定好好的自己理解一遍,並把它記

SVD在推薦系統中的應用以及演算法推導

前面文章SVD原理及推導已經把SVD的過程講的很清楚了,本文介紹如何將SVD應用於推薦系統中的評分預測問題。其實也就是復現Koren在NetFlix大賽中的使用到的SVD演算法以及其擴展出的RSVD、SVD++。    記得剛接觸SVD是在大二,那會兒跟師兄在做專案的時候就

(轉載)token以及應用原理

一、我們先解釋一下Token的含義 1、Token的引入: Token是在客戶端頻繁向服務端請求資料,服務端頻繁的去資料庫查詢使用者名稱和密碼並進行對比,判斷使用者名稱和密碼正確與否,並作出相應提示,在這樣的背景下,Token便應運而生。 2、Token的定義: Token是服務端生成的一串字串,以

JVM的記憶體區域劃分以及垃圾回收機制

在我們寫Java程式碼時,大部分情況下是不用關心你New的物件是否被釋放掉,或者什麼時候被釋放掉。因為JVM中有垃圾自動回收機制。在之前的部落格中我們聊過Objective-C中的MRC(手動引用計數)以及ARC(自動引用計數)的記憶體管理方式,下方會對其進行回顧。而目前的JVM的記憶體回收機制則不是使用的引

java反射機制應用

1反射機制是什麼 反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。 2反射機制能做什麼 反射機制主要提供了以下功能: 在執行

【Oracle】v$session

ilove error datafile ase 實例 ted lba terminal 內存 首先查看一下v$session都存在哪些列 SYS@ORCL>desc v$session Name

爬蟲原理與會話保持(cookies、session--python實現

一、爬蟲原理     我們知道網際網路是由大量計算機和網路構成的複雜系統,我們可以將其形象的比喻成一張蜘蛛網。網路的節點是計算機,計算機中儲存著大量的資料。爬蟲程式就是通過網路去採集指定計算機中資料的工具。一般來說,我們採集的資料大多是網頁上的資料,

ActiveMQ訊息傳送機制以及ACK機制 AcitveMQ是作為一種訊息儲存和分發元件,涉及到client與broker端資料互動的方方面面,它不僅要擔保訊息的儲存安全性,還要提供額外的

    AcitveMQ是作為一種訊息儲存和分發元件,涉及到client與broker端資料互動的方方面面,它不僅要擔保訊息的儲存安全性,還要提供額外的手段來確保訊息的分發是可靠的。 一. ActiveMQ訊息傳送機制     Producer客戶端使用來發送訊息的, Consumer客戶端用來消費