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