以前實現數據的緩存有很多種方法,有客戶端的Cookie,有服務器端的Session和Application。
其中Cookie是保存在客戶端的一組數據,主要用來保存用戶名等個人信息。
Session則保存對話信息。Application則是保存在整個應用程序范圍內的信息,相當于全局變量。
## Session
Session用來保存每一個用戶的專有信息
Session的生存期是用戶持續請求時間加上一段時間(一般是20分鐘左右)
Session信息是保存在Web服務器內存中的,保存數據量可大可小
由于用戶停止使用應用程序之后它仍在內存中存留一段時間,因此這種方法效率較低
代碼:
~~~
Session[“UserID”]=”test”;
String UserName=Session[“UserID”].ToString();
~~~
## Cookie
Cookie用來保存客戶瀏覽器請求服務器頁面的請求信息
我們可以存放非敏感的用戶信息,保存時間可以根據需要設置
如果沒有設置Cookie失效日期,它的生命周期保存到關閉瀏覽器為止
Cookie對象的Expires屬性設置為MinValue表示永不過期
Cookie存儲的數據量受限制,大多數的瀏覽器為4K因此不要存放大數據
由于并非所有的瀏覽器都支持Cookie,數據將以明文的形式保存在客戶端
代碼:
~~~
Resopnse.Cookies[“UserID”]=”test”;
String UserName= Resopnse.Cookies [“UserID”].ToString();
~~~
## Cache
Cache用于在Http請求期間保存頁面或者數據
Cache的使用可以大大的提高整個應用程序的效率
它允許將頻繁訪問的服務器資源存儲在內存中,當用戶發出相同的請求后,服務器不是再次處理而是將Cache中保存的數據直接返回給用戶
可以看出Cache節省的是時間—服務器處理時間
Cache實例是每一個應用程序專有的,其生命周期==該應用程序周期
應用程序重啟將重新創建其實例
注意:如果要使用緩存的清理、到期管理、依賴項等功能必須使用Insert 或者Add方法方法添加信息
代碼:
~~~
Cache[”ID”]=”cc”;或者Cache.Insert(“ID”,”test”);
String ID =Cache[“ID”].ToString();
~~~
## Session緩存和Cache緩存的區別
通常使用最頻繁的是Session,那么Session和Cache又有什么區別呢?
(1)最大的區別是Cache提供緩存依賴來更新數據,而Session只能依靠定義的緩存時間來判斷緩存數據是否有效。
(2)即使應用程序終止,只要Cache.Add方法中定義的緩存時間未過期,下次開啟應用程序時,緩存的數據依然存在。而Session緩存只是存在于一次會話中,會話結束后,數據也就失效了。
(3)Session容易丟失,導致數據的不確定性,而Cache不會出現這種情況。
(4)由于Session是每次會話就被加載,所以不適宜存放大量信息,否則會導致服務器的性能降低。而Cache則主要用來保存大容量信息,如數據庫中的多個表。
(5)Session目前只能保存在內存中,對其性能有影響。
Session:為當前用戶會話提供信息。還提供對可用于存儲信息的會話范圍的緩存的訪問,以及控制如何管理會話的方法。它存儲在服務器的內存中,因此與在數據庫中存儲和檢索信息相比,它的執行速度更快。與不特定于單個用戶會話的應用程 序狀態不同,會話狀態應用于單個的用戶和會話。因此,應用程序狀態非常適合存儲那些數量少、隨用戶的變化而變化的常用數據。而且由于其不發生服務器-客戶 端數據傳輸,Session還適合存儲關于用戶的安全數據,如購物車信息。
Session的關鍵特性有:存儲于服務器內存中,與會話相關,在會話的整個生存期中存在即不會被主動丟棄,不被序列化,不發生服務器-客戶端數據傳輸。
Cache:它存儲于 服務器的內存中,允許您自定義如何緩存項以及將它們緩存多長時間。例如,當缺乏系統內存時,緩存會自動移除很少使用的或優先級較低的項以釋放內存。該技術 也稱為清理,這是緩存確保過期數據不使用寶貴的服務器資源的方式之一。它不與會話相關,所以它是多會話共享的,因此使用它可以提高網站性能,但是可能泄露 用戶的安全信息,還由于在服務器缺乏內存時可能會自動移除Cache因此需要在每次獲取數據時檢測該Cache項是否還存在。
Cache的關鍵特性有:存儲于服務器內存中,與會話無關,根據服務器內存資源的狀況隨時可能被丟棄,不被序列化,不發生服務器-客戶端數據傳輸。
Cookie:Cookie 提供了一種在 Web 應用程序中存儲用戶特定信息的方法。例如,當用戶訪問您的站點時,您可以使用 Cookie 存儲用戶首選項或其他信息。當該用戶再次訪問您的網站時,應用程序便可以檢索以前存儲的信息。在開發人員以編程方式設置Cookie時,需要將自己希望保 存的數據序列化為字符串(并且要注意,很多瀏覽器對Cookie有4096字節的限制)然后進行設置。
Cookie的關鍵特性有:存儲于客戶端硬盤上,與用戶相關,在一定時間內持久化存儲,可以跨瀏覽器共享數據,需要被序列化,發生服務器-客戶端數據傳輸。
* * * * *
* * * * *
## 另一篇文章
sessionid是一個會話的key,瀏覽器第一次訪問服務器會在服務器端生成一個session,有一個sessionid和它對應。tomcat生成的sessionid叫做jsessionid。
session在訪問tomcat 服務器HttpServletRequest的getSession(true)的時候 創建,tomcat的ManagerBase類提供創建sessionid的方法: 隨機數+時間+jvmid;
存儲在服務器的內存中,tomcat的StandardManager類將session 存儲在內存中,也可以持久化到file,數據庫,memcache,redis等。 客戶端只保存sessionid到cookie中,而不會保存session,session銷毀只能通過invalidate或超時,關掉瀏覽器并不會關閉session。
那么Session在何時創建呢?當然還是在服務器端程序運行的過程中創建的,不同語言實現的應用程序有不同創建Session的方法,而在Java中是通過調用HttpServletRequest的getSession方法(使用true作為參數)創建的。在創建了Session的同時,服務器會為該Session生成唯一的Session id,而這個Session id在隨后的請求中會被用來重新獲得已經創建的Session;在Session被創建之后,就可以調用Session相關的方法往Session中增加內容了,而這些內容只會保存在服務器中,發到客戶端的只有Session id;當客戶端再次發送請求的時候,會將這個Session id帶上,服務器接受到請求之后就會依據Session id找到相應的Session,從而再次使用之。
**創建**:sessionid第一次產生是在直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被創建。
**刪除**:超時;程序調用HttpSession.invalidate();程序關閉;
**session存放在哪里**:服務器端的內存中。不過session可以通過特殊的方式做持久化管理(memcache,redis)。
**session的id是從哪里來的**,sessionID是如何使用的:當客戶端第一次請求session對象時候,服務器會為客戶端創建一個session,并將通過特殊算法算出一個session的ID,用來標識該session對象
**session會因為瀏覽器的關閉而刪除嗎**?
不會,session只會通過上面提到的方式去關閉。
下面是tomcat中session的創建:
ManagerBase是所有session管理工具類的基類,它是一個抽象類,所有具體實現session管理功能的類都要繼承這個類,該類有一個受保護的方法,該方法就是創建sessionId值的方法:
( tomcat的session的id值生成的機制是一個隨機數加時間加上jvm的id值,jvm的id值會根據服務器的硬件信息計算得來,因此不同jvm的id值都是唯一的),
StandardManager類是tomcat容器里默認的session管理實現類,
它會將session的信息存儲到web容器所在服務器的內存里。
PersistentManagerBase也是繼承ManagerBase類,它是所有持久化存儲session信息的基類,PersistentManager繼承了PersistentManagerBase,但是這個類只是多了一個靜態變量和一個getName方法,目前看來意義不大, 對于持久化存儲session,tomcat還提供了StoreBase的抽象類,它是所有持久化存儲session的基類,另外tomcat還給出了文件存儲FileStore和數據存儲JDBCStore兩個實現。
瀏覽器禁用cookie后,怎么使用session,解決方案:
sessionid是存儲在cookie中的,解決方案如下:
Session URL重寫,保證在客戶端禁用或不支持COOKIE時,仍然可以使用Session
**session機制**:session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。
當程序需要為某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端創建過session,服務器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。 保存這個session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發揮給服務器。一般這個cookie的名字都是類似于 SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。 經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的后面。還有一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。比如:
`<form name=”"testform”" action=”"/xxx”"> <input type=”"hidden”" name=”"jsessionid”" value=”"ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764″”> <input type=”"text”"> </form>`
URL重寫:
`http://www.test.com/test;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764`
目前,為了使web能適應大規模的訪問,需要實現應用的集群部署. 而實現集群部署首先要解決session的統一,即需要實現**session的共享機制**。
目前,在集群系統下實現session統一的有如下幾種方案:
(1) 應用服務器間的session復制共享(如tomcat session共享)
(2) 基于cache DB緩存的session共享
#### 應用服務器間的session復制共享
session復制共享,主要是指集群環境下,多臺應用服務器之間同步session,使session保持一致,對外透明。 如果其中一臺服務器發生故障,根據負載均衡的原理,web服務器(apache/nginx)會遍歷尋找可用節點,分發請求,由于session已同步, 故能保證用戶的session信息不會丟失。
此方案的不足之處:
* 技術復雜,必須在同一種中間件之間完成(如:tomcat-tomcat之間)。
* session復制帶來的性能損失會快速增加.特別是當session中保存了較大的對象,而且對象變化較快時, 性能下降更加顯著. 這種特性使得web應用的水平擴展受到了限制。
* Session內容序列化(serialize),會消耗系統性能。
* Session內容通過廣播同步給成員,會造成網絡流量瓶頸,即便是內網瓶頸。
#### 基于cache DB緩存的session共享
即使用cacheDB存取session信息,應用服務器接受新請求將session信息保存在cache DB中,當應用服務器發生故障時,web服務器(apache/nginx)會遍歷尋找可用節點,分發請求,當應用服務器發現session不在本機內存 時,則去cache DB中查找,如果找到則復制到本機,這樣實現session共享和高可用。
目前有開源的msm用于解決tomcat之間的session共享:Memcached_Session_Manager(MSM)
`http://code.google.com/p/memcached-session-manager/`
一個高可用的Tomcat session共享解決方案,除了可以從本機內存快速讀取Session信息(僅針對黏性Session)外,同時可使用memcached存取Session,以實現高可用。
特性
* 支持Tomcat6、Tomcat7支持黏性、非黏性Session
* 無單一故障點
* 可處理tomcat故障轉移
* 可處理memcached故障轉移
* 插件式session序列化
* 允許異步保存session,以提升響應速度
* 只有當session有修改時,才會將session寫回memcached
* JMX管理&監控
該方案的不足之處:
* memcache支持的數據結構比較單一
* memcache的內存必須足夠大,否則會出現用戶session從Cache中被清除
* 需要定期的刷新緩存
* 服務器故障時,存在于內存的memcache數據將會丟失
為了解決基于memcache中存在的不足,故提出了下面的一種解決方案:
#### 基于redis緩存的session共享
結合上面的 MSM 思想,由 redis負責 session 數據的存儲,而我們自己實現的 session manager 將負責 session 生命周期的管理。
此架構存在著當redis master故障時, 雖然可以有一到多個備用slave,但是redis不會主動的進行master切換,這時session服務中斷。
為了做到redis的高可用,引入了zookper或者haproxy或者keepalived來解決redis master slave的切換問題。即:
此體系結構中, redis master出現故障時, 通過haproxy設置redis slave為臨時master, redis master重新恢復后,再切換回去. 此方案中, redis-master 與redis-slave 是雙向同步的, 解決目前redis單點問題. 這樣保證了session信息在redis中的高可用。
- java
- 設計模式
- 設計模式總覽
- 設計原則
- 工廠方法模式
- 抽象工廠模式
- 單例模式
- 建造者模式
- 原型模式
- 適配器模式
- 裝飾者模式
- 代理模式
- 外觀模式
- 橋接模式
- 組合模式
- 享元模式
- 策略模式
- 模板方法模式
- 觀察者模式
- 迭代子模式
- 責任鏈模式
- 命令模式
- 備忘錄模式
- 狀態模式
- 訪問者模式
- 中介者模式
- 解釋器模式
- 附錄
- JVM相關
- JVM內存結構
- Java虛擬機的內存組成以及堆內存介紹
- Java堆和棧
- 附錄-數據結構的堆棧和內存分配的堆區棧區的區別
- Java內存之Java 堆
- Java內存之虛擬機和內存區域概述
- Java 內存之方法區和運行時常量池
- Java 內存之直接內存(堆外內存)
- JAVA內存模型
- Java內存模型介紹
- 內存模型如何解決緩存一致性問題
- 深入理解Java內存模型——基礎
- 深入理解Java內存模型——重排序
- 深入理解Java內存模型——順序一致性
- 深入理解Java內存模型——volatile
- 深入理解Java內存模型——鎖
- 深入理解Java內存模型——final
- 深入理解Java內存模型——總結
- 內存可見性
- JAVA對象模型
- JVM內存結構 VS Java內存模型 VS Java對象模型
- Java的對象模型
- Java的對象頭
- HotSpot虛擬機
- HotSpot虛擬機對象探秘
- 深入分析Java的編譯原理
- Java虛擬機的鎖優化技術
- 對象和數組并不是都在堆上分配內存的
- 垃圾回收
- JVM內存管理及垃圾回收
- JVM 垃圾回收器工作原理及使用實例介紹
- JVM內存回收理論與實現(對象存活的判定)
- JVM參數及調優
- CMS GC日志分析
- JVM實用參數(一)JVM類型以及編譯器模式
- JVM實用參數(二)參數分類和即時(JIT)編譯器診斷
- JVM實用參數(三)打印所有XX參數及值
- JVM實用參數(四)內存調優
- JVM實用參數(五)新生代垃圾回收
- JVM實用參數(六) 吞吐量收集器
- JVM實用參數(七)CMS收集器
- JVM實用參數(八)GC日志
- Java性能調優原則
- JVM 優化經驗總結
- 面試題整理
- 面試題1
- java日志規約
- Spring安全
- OAtuth2.0簡介
- Spring Session 簡介(一)
- Spring Session 簡介(二)
- Spring Session 簡介(三)
- Spring Security 簡介(一)
- Spring Security 簡介(二)
- Spring Security 簡介(三)
- Spring Security 簡介(四)
- Spring Security 簡介(五)
- Spring Security Oauth2 (一)
- Spring Security Oauth2 (二)
- Spring Security Oauth2 (三)
- SpringBoot
- Shiro
- Shiro和Spring Security對比
- Shiro簡介
- Session、Cookie和Cache
- Web Socket
- Spring WebFlux