黨建專欄 文字說(shuō)明 網(wǎng)站建設(shè)福州seo網(wǎng)站排名
一、Cookie
1、什么是Cookie
1、Cookie實(shí)際上是一小段的文本信息,是一種key=value形式的字符串。客戶端請(qǐng)求服務(wù)器,如果服務(wù)器需要記錄該用戶狀態(tài),就使用response向客戶端瀏覽器頒發(fā)一個(gè)Cookie??蛻舳藭?huì)把Cookie保存起來(lái)。
2、當(dāng)瀏覽器再請(qǐng)求該網(wǎng)站時(shí),瀏覽器把請(qǐng)求的網(wǎng)址連同該Cookie一同提交給服務(wù)器。服務(wù)器檢查該Cookie,以此來(lái)辨認(rèn)用戶狀態(tài)。服務(wù)器還可以根據(jù)需要修改Cookie的內(nèi)容。
3、cookie 只存儲(chǔ)用戶的身份標(biāo)識(shí),如用一串字符串表示的 userid;服務(wù)器端通過(guò) session 存儲(chǔ)用戶信息,然后用 userid 去查找對(duì)應(yīng)的用戶信息。
4、Cookie是客戶端(瀏覽器)存儲(chǔ)數(shù)據(jù)的一種機(jī)制,鍵值對(duì)結(jié)構(gòu),可以存儲(chǔ)身份信息,也是可以存儲(chǔ)關(guān)鍵的信息,都是程序員自定義
5、Cookie是瀏覽器提供的一種讓程序員在本地存儲(chǔ)數(shù)據(jù)的能力,讓數(shù)據(jù)在客戶端這邊更持久化。
2、會(huì)話Cookie和持久Cookie
1、會(huì)話cookie(內(nèi)存式Cookie):
若不設(shè)置過(guò)期時(shí)間,則表示這個(gè)cookie的生命期為瀏覽器會(huì)話期間,關(guān)閉瀏覽器窗口,cookie就消失。這種生命期為瀏覽器會(huì)話期的cookie被稱為會(huì)話cookie。會(huì)話cookie一般不存儲(chǔ)在硬盤上而是保存在內(nèi)存里,當(dāng)然這種行為并不是規(guī)范規(guī)定的。
2、持久Cookie(硬盤式Cookie):
若設(shè)置了過(guò)期時(shí)間,瀏覽器就會(huì)把cookie保存到硬盤上,關(guān)閉后再次打開(kāi)瀏覽器,這些cookie仍然有效直到超過(guò)設(shè)定的過(guò)期時(shí)間。存儲(chǔ)在硬盤上的cookie可以在瀏覽器的不同進(jìn)程間共享。這種稱為持久Cookie。
3、Cookie具有不可跨域名性
你在逛B站時(shí)生成的cookie,不會(huì)被帶到CSDN的cookie中。
4、Cookie的工作原理
瀏覽器里面存的Cookie都是從服務(wù)器的響應(yīng)“報(bào)頭”里面的 set-cookie 字段中來(lái)的,每個(gè) set-cookie 字段里面都包含一個(gè)Cookie 這樣的鍵值對(duì),瀏覽器拿到響應(yīng)之后就會(huì)把 set-cookie中的內(nèi)容保存到本地,而 set-cookie 就是程序員自己在服務(wù)器中構(gòu)造填寫(xiě)的。
注意:
1、修改和刪除cookie
- 要想修改Cookie只能使用一個(gè)同名的Cookie來(lái)覆蓋原來(lái)的Cookie,達(dá)到修改的目的。
- 修改、刪除Cookie時(shí),新建的Cookie除value、maxAge之外的所有屬性,例如name、path、domain等,都要與原Cookie完全一樣。否則,瀏覽器將視為兩個(gè)不同的Cookie不予覆蓋,導(dǎo)致修改、刪除失敗。
- 從客戶端讀取Cookie時(shí),包括maxAge在內(nèi)的其他屬性都是不可讀的,也不會(huì)被提交。瀏覽器提交Cookie時(shí)只會(huì)提交name與value屬性。maxAge屬性只被瀏覽器用來(lái)判斷Cookie是否過(guò)期。
2、配置域名
- domain參數(shù)必須以點(diǎn)(“.”)開(kāi)始。另外,name相同但domain不同的Cookie是兩個(gè)不同的Cookie。如果想要兩個(gè)域名完全不同的網(wǎng)站共有Cookie,可以生成兩個(gè)Cookie,domain屬性分別為兩個(gè)域名,輸出到客戶端。
3、配置允許訪問(wèn)Cookie的路徑
- 設(shè)置為“/”時(shí)允許所有路徑使用Cookie。path屬性需要使用符號(hào)“/”結(jié)尾。
4、配置cookie的安全屬性
- secure屬性并不能對(duì)Cookie內(nèi)容加密,因而不能保證絕對(duì)的安全性。如果需要高安全性,需要在程序中對(duì)Cookie內(nèi)容加密、解密,以防泄密。
- 如果不希望Cookie在HTTP等非安全協(xié)議中傳輸,可以設(shè)置Cookie的secure屬性為true。瀏覽器只會(huì)在HTTPS和SSL等安全協(xié)議中傳輸此類Cookie。
二、Session
1、什么是Session
1、Session是另一種記錄客戶狀態(tài)的機(jī)制,不同的是 Cookie保存在客戶端瀏覽器中,而Session保存在服務(wù)器上??蛻舳藶g覽器訪問(wèn)服務(wù)器的時(shí)候,服務(wù)器把客戶端信息以Session記錄在服務(wù)器上。
2、session 運(yùn)行在服務(wù)器端,當(dāng)客戶端第一次訪問(wèn)服務(wù)器時(shí),可以將用戶的登錄信息保存;當(dāng)用戶訪問(wèn)其他界面時(shí),可以通過(guò) session 判斷用戶的登錄狀態(tài),做出提示。
3、Session是服務(wù)器存儲(chǔ)數(shù)據(jù)的一種機(jī)制,鍵值對(duì)結(jié)構(gòu)的,主要用來(lái) 存儲(chǔ)身份相關(guān)的信息。
2、Session的工作原理
Session在調(diào)用getSession()或者getSession(true),底層都會(huì)自動(dòng)實(shí)現(xiàn)Set-Cookie方法,這意味著使用
session會(huì)生成cookie存放JSESSIONID。
【getSession()或者getSession(true) 返回的是key=value的cookie鍵值對(duì)】
注意:
1、getSession(Boolean)
- 如果參數(shù)是true,就會(huì)看看請(qǐng)求中是否會(huì)有 SessionId,以及SessionId合不合法。
1、如果有SessionId,就會(huì)根據(jù)這個(gè)SessiuonId找到對(duì)應(yīng) HttpServlet 對(duì)象(查hash表),在服務(wù)器這邊以一個(gè)hash表的形式,把若干個(gè)Session給組織起來(lái);
2、如果沒(méi)有SessionId,那么服務(wù)器就會(huì)生成一個(gè)SessionId,同時(shí)創(chuàng)建一個(gè)HttpServlet 對(duì)象,把這一組鍵值對(duì)再插入到服務(wù)器管理的Session的hash表中,同時(shí)把 sessionId,通過(guò)Set-cookie 在響應(yīng)中返回給客服端- 如果參數(shù)是false,也是會(huì)看請(qǐng)求中是否有SessionId,以及是否合法,如果有SessionId,直接找到對(duì)應(yīng)的 HttpServlet對(duì)象,查詢各方面的信息,如果沒(méi)有SessionId,那么直接返回就是null
2、保存session id的方式
- 1.使用Cookie進(jìn)行保存(默認(rèn)機(jī)制);2.URL重寫(xiě);3.表單隱藏字段
3、Session的生命周期和有效期設(shè)置
- Session保存在服務(wù)器端。為了獲得更高的存取速度,服務(wù)器一般把Session放在內(nèi)存里。每個(gè)用戶都會(huì)有一個(gè)獨(dú)立的Session。如果Session內(nèi)容過(guò)于復(fù)雜,當(dāng)大量客戶訪問(wèn)服務(wù)器時(shí)可能會(huì)導(dǎo)致內(nèi)存溢出。因此,Session里的信息應(yīng)該盡量精簡(jiǎn)。
- 由于會(huì)有越來(lái)越多的用戶訪問(wèn)服務(wù)器,因此Session也會(huì)越來(lái)越多。為防止內(nèi)存溢出,服務(wù)器會(huì)把長(zhǎng)時(shí)間內(nèi)沒(méi)有活躍的Session從內(nèi)存刪除。這個(gè)時(shí)間就是Session的超時(shí)時(shí)間。如果超過(guò)了超時(shí)時(shí)間沒(méi)訪問(wèn)過(guò)服務(wù)器,Session就自動(dòng)失效了。
- 注意:< session-timeout >參數(shù)的單位為分鐘,而setMaxInactiveInterval(int s)單位為秒。
疑惑:對(duì)于Session和Cookie的關(guān)系
回答:Cookie是在客戶端存放Session的;調(diào)用Session本身就會(huì)用到Cookie(工作原理),如果不想用也可用另外兩種方式實(shí)現(xiàn)(不建議,最好使用Cookie)。
3、Cookie和Session的區(qū)別
1、cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。
2、cookie不是很安全,別人可以分析存放在本地的cookie并進(jìn)行cookie欺騙,考慮到安全應(yīng)當(dāng)使用session。
3、session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問(wèn)增多,會(huì)比較占用你服務(wù)器的性能,考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用cookie。
4、單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。
5、可以考慮將登陸信息等重要信息存放為session,其他信息如果需要保留,可以放在cookie中。
三、Redis
1、什么是Redis
Redis(Remote Dictionary Server ),即遠(yuǎn)程字典服務(wù),是一個(gè)開(kāi)源的使用ANSI C語(yǔ)言編寫(xiě)、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫(kù),并提供多種語(yǔ)言的API。
2、為什么要用Redis(Session為什么要結(jié)合Redis使用)
實(shí)際的項(xiàng)目中,需要部署在多臺(tái)服務(wù)器上,防止某臺(tái)服務(wù)器的壓力過(guò)大,避免出現(xiàn)系統(tǒng)性能問(wèn)題或宕機(jī)。
eg1.舉例說(shuō)明(只用session和cookie)
對(duì)于登錄系統(tǒng),用戶主要訪問(wèn)我們nginx的代理服務(wù)器請(qǐng)求系統(tǒng)。
如果用戶第一次請(qǐng)求被分配到了服務(wù)器A,創(chuàng)建的Session對(duì)象就是在A的內(nèi)存中,返回給用戶的Cookie是JSESSIONID=abc123;用戶第二次請(qǐng)求用Cookie找到值為abc123的session就不需要再次登錄了,但是,第二次請(qǐng)求分配到了服務(wù)器B,拿著abc123在B的內(nèi)存中根本沒(méi)有,就會(huì)出現(xiàn)請(qǐng)求失敗,用戶就得再次輸入密碼才能登錄,用戶體驗(yàn)就很差。
eg2.舉例說(shuō)明(使用redis實(shí)現(xiàn)session共享)
加入redis后,用戶第一次請(qǐng)求的session被存放到Redis中,即使第二次請(qǐng)求到了服務(wù)器B,也可以從redis查到對(duì)應(yīng)的session。
PS:感覺(jué)Redis就是單純的替代了每個(gè)服務(wù)器存儲(chǔ)session,實(shí)現(xiàn)共享。
Session為什么要結(jié)合Redis使用
- 分布式數(shù)據(jù)存儲(chǔ)
Session數(shù)據(jù)保存在內(nèi)存中,如果有多個(gè)Web服務(wù)器組成的集群,那么Session數(shù)據(jù)就會(huì)分散在各個(gè)服務(wù)器上,導(dǎo)致Session數(shù)據(jù)無(wú)法共享。Redis的主要作用是支持分布式數(shù)據(jù)存儲(chǔ),因此可以解決這個(gè)問(wèn)題,讓多個(gè)Web服務(wù)器上的Session數(shù)據(jù)共享。- 高性能
Redis是一種高性能的內(nèi)存數(shù)據(jù)庫(kù),它可以處理大量的讀寫(xiě)請(qǐng)求,使得Session數(shù)據(jù)的讀寫(xiě)速度大大提高,從而提升Web應(yīng)用程序的性能。- 支持持久化存儲(chǔ)
Redis支持將數(shù)據(jù)持久化到磁盤中,確保Session數(shù)據(jù)不會(huì)因?yàn)榉?wù)器宕機(jī)或關(guān)機(jī)而丟失。這樣可以最大程度上保障用戶數(shù)據(jù)的安全性和可靠性。- 支持高并發(fā)
由于Redis的高并發(fā)性能,可以支撐大量用戶同時(shí)訪問(wèn)Web應(yīng)用程序,從而提高并發(fā)用戶數(shù)的處理能力,減少了Web應(yīng)用程序出現(xiàn)瓶頸的風(fēng)險(xiǎn)。- 強(qiáng)大的擴(kuò)展能力
Redis支持豐富的數(shù)據(jù)結(jié)構(gòu)和功能,可以根據(jù)需要擴(kuò)展和定制Session管理的功能,讓Session管理更加靈活和高效。
3、簡(jiǎn)單擴(kuò)展
3.1 什么叫做緩存穿透?如何解決?
是指緩存和數(shù)據(jù)庫(kù)中都沒(méi)有數(shù)據(jù),導(dǎo)致所有的請(qǐng)求都落到數(shù)據(jù)庫(kù)上。數(shù)據(jù)庫(kù)短時(shí)間承受大量的請(qǐng)求而崩掉
解決:
1緩存取不到,數(shù)據(jù)庫(kù)也取不到的數(shù)據(jù), 設(shè)置為key—null 的方式
2布隆過(guò)濾器,將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap 中去(它告訴你存在的話不能全信,其實(shí)有可能是不存在的,不過(guò)它他要是告訴你不存在的話,那就一定不存在)
3.2 什么叫做緩存擊穿?如何解決?
高并發(fā)查詢同一條數(shù)據(jù),但是redis 中的數(shù)據(jù)過(guò)期了。導(dǎo)致請(qǐng)求發(fā)送到了數(shù)據(jù)庫(kù),造成緩存擊穿
解決:
1設(shè)置熱點(diǎn)數(shù)據(jù)永不過(guò)期;
2使用互斥鎖。分布式情況下使用分布式的鎖
3.3 什么叫做緩存雪崩?如何解決?
緩存同一時(shí)間大面積的失效,后面的請(qǐng)求都會(huì)落到數(shù)據(jù)庫(kù)上,造成數(shù)據(jù)庫(kù)短時(shí)間內(nèi)承受大量的數(shù)據(jù)請(qǐng)求
解決:
緩存數(shù)據(jù)的過(guò)期時(shí)間隨機(jī)設(shè)置,防止同一時(shí)間大量的數(shù)據(jù)過(guò)期的情況發(fā)生
3.4 Redis查詢?yōu)槭裁春芸?#xff1f;
雖然redis是單線程程序,但是因?yàn)樗羌儍?nèi)存數(shù)據(jù)庫(kù),只操作內(nèi)存(而我們的mysql是硬盤操作),并且使用了異步非阻塞IO(單線程+多路復(fù)用IO模型)
3.5 什么是多路復(fù)用IO?
當(dāng)一個(gè)請(qǐng)求訪問(wèn)redis時(shí),redis去取數(shù)據(jù)給這個(gè)請(qǐng)求的時(shí)間段內(nèi),請(qǐng)求的入口不是阻塞的,也就是說(shuō)依舊可以接收請(qǐng)求,直到redis取到數(shù)據(jù),再一一響應(yīng)這些請(qǐng)求。
多路:多個(gè)socket連接,復(fù)用:復(fù)用一個(gè)線程
多路I/O復(fù)用技術(shù)可以讓單個(gè)線程高效的處理多個(gè)連接請(qǐng)求(盡量的減少網(wǎng)絡(luò)IO的時(shí)間消耗)。
3.6 為什么單線程查詢速度能這么快?
首先,單線程肯定不可能比多線程快,但是單線程的模式避免了數(shù)據(jù)并發(fā)安全(因?yàn)槎嗑€程的數(shù)據(jù)并發(fā)安全,所以出現(xiàn)了各種鎖)。那么這個(gè)時(shí)候我們單線程的優(yōu)點(diǎn)就來(lái)了:不需要考慮數(shù)據(jù)并發(fā)的安全,也不用出現(xiàn)頻繁的線程調(diào)度,切換上下文。
3.7 上下文是什么?
線程每次執(zhí)行時(shí)都需要將數(shù)據(jù)從主內(nèi)存讀入到工作內(nèi)存中。當(dāng)線程阻塞時(shí),工作內(nèi)存的數(shù)據(jù)就需要被放到線程上下文中,其實(shí)線程上下文就是一個(gè)存儲(chǔ)結(jié)構(gòu),當(dāng)線程被喚醒的時(shí)候,就去讀取上下文的內(nèi)容,就稱為切換上下文。
3.8 主內(nèi)存和工作內(nèi)存是什么?
主內(nèi)存(Main Memory)是用于計(jì)算機(jī)內(nèi)部存儲(chǔ)和訪問(wèn)數(shù)據(jù)的一種硬件設(shè)備,通常指的是隨機(jī)訪問(wèn)存儲(chǔ)器(RAM)。它在計(jì)算機(jī)啟動(dòng)時(shí)被激活,并且一直運(yùn)行到計(jì)算機(jī)關(guān)閉。主內(nèi)存通常是存放程序和數(shù)據(jù)的地方,因此也被稱為程序級(jí)存儲(chǔ)器(Programmable Memory)。在主內(nèi)存中,數(shù)據(jù)存儲(chǔ)在內(nèi)存單元中,每個(gè)內(nèi)存單元具有一個(gè)唯一的地址。
工作內(nèi)存(Working Memory)通常是指線程(Thread)執(zhí)行時(shí)使用的緩存區(qū)域,也被稱為線程的本地內(nèi)存(Thread Local Memory)。每個(gè)線程都有自己的工作內(nèi)存,線程的工作內(nèi)存中存儲(chǔ)了該線程獨(dú)享的變量副本(Copy),工作內(nèi)存中的變量副本會(huì)被操作后寫(xiě)回主內(nèi)存。多個(gè)線程之間可以訪問(wèn)共享的數(shù)據(jù),如果一個(gè)線程要訪問(wèn)共享的變量,它會(huì)先將變量從主內(nèi)存復(fù)制到自己的工作內(nèi)存中,然后對(duì)變量進(jìn)行操作,最后將變量的值寫(xiě)回到主內(nèi)存中。
需要注意的是,多個(gè)線程互相之間不能看到各自工作內(nèi)存中存儲(chǔ)的數(shù)據(jù),這些數(shù)據(jù)只會(huì)在各自的工作內(nèi)存和主內(nèi)存之間傳遞。因此,為了確保線程間的數(shù)據(jù)一致性,Java 提供了一些同步機(jī)制,如 synchronized 關(guān)鍵字和 Lock 接口,當(dāng)一個(gè)線程需要訪問(wèn)共享的數(shù)據(jù)時(shí),需要先獲取鎖,保證其他線程暫時(shí)無(wú)法修改該數(shù)據(jù),然后才能進(jìn)行操作。這些同步機(jī)制確保了數(shù)據(jù)在多個(gè)線程之間的可見(jiàn)性和一致性,避免了并發(fā)訪問(wèn)時(shí)的數(shù)據(jù)競(jìng)爭(zhēng)和錯(cuò)誤。
read(讀取):作用于主內(nèi)存變量,把一個(gè)變量值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便隨后的load動(dòng)作使用
load(載入):作用于工作內(nèi)存的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中。
use(使用):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個(gè)變量值傳遞給執(zhí)行引擎,每當(dāng)虛擬機(jī)遇到一個(gè)需要使用變量的值的字節(jié)碼指令時(shí)將會(huì)執(zhí)行這個(gè)操作。
assign(賦值):作用于工作內(nèi)存的變量,它把一個(gè)從執(zhí)行引擎接收到的值賦值給工作內(nèi)存的變量,每當(dāng)虛擬機(jī)遇到一個(gè)給變量賦值的字節(jié)碼指令時(shí)執(zhí)行這個(gè)操作。
store(存儲(chǔ)):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個(gè)變量的值傳送到主內(nèi)存中,以便隨后的write的操作。
write(寫(xiě)入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中一個(gè)變量的值傳送到主內(nèi)存的變量中。
==================================
本文參考了以下文章,他們的描述更加詳細(xì):
Cookie 和 Session
Cookie和Session的區(qū)別(面試必備)
Cookie和Session詳解
Session和Cookie的區(qū)別與聯(lián)系【nodejs學(xué)習(xí)筆記】用戶登錄相關(guān):cookie、session 和 redis的使用和優(yōu)缺點(diǎn)
Node.js坑點(diǎn)雜談(二)快速弄懂session和redis
session + redis 實(shí)現(xiàn)session 共享原理和原因
session與cookie的理解(sso、redis)
redis詳解(全)
Redis 詳解