秦溧 艾青



摘要:針對Web服務(wù)器不能對用戶訪問系統(tǒng)時所產(chǎn)生的無狀態(tài)會話進行有效管理,提出采用Redis緩存服務(wù)器技術(shù)來管理用戶端和服務(wù)器之間所產(chǎn)生的無狀態(tài)會話,并通過實驗證實了采用該技術(shù)能有效管理用戶訪問系統(tǒng)所產(chǎn)生的無狀態(tài)會話,同時還可以優(yōu)化系統(tǒng)性能,提高用戶體驗感。
關(guān)鍵詞:Redis緩存;Session;會話管理
中圖分類號:TP311.5? ? ? 文獻標(biāo)識碼:A
文章編號:1009-3044(2021)12-0090-03
1 背景
HTTP協(xié)議屬于無狀態(tài)分布式通信協(xié)議,也就是服務(wù)器每響應(yīng)一次用戶請求后就會丟失和用戶之間的聯(lián)系,因此當(dāng)接收下一個用戶請求時無法判斷該請求是否來自相同的用戶,也就無法有效地去記錄用戶所進行的操作和用戶的狀態(tài)等重要信息。而在Web應(yīng)用中,通常需要記錄和跟蹤用戶的會話狀態(tài),用于對用戶進行身份認(rèn)證、訪問控制等[1]。
而伴隨著需求的增長,對用戶的登錄,權(quán)限等狀態(tài)的會話信息管理已成為不可避免的話題。平常在進行Web開發(fā)時,需要和Web服務(wù)進行打交道,Web服務(wù)是種無狀態(tài)的會話機制和HTTP協(xié)議類似。因此要對用戶的會話狀態(tài)進行管理則需要使用其他的方式進行實現(xiàn)。
基于此,本文采用Redis分布式緩存技術(shù)設(shè)計并實現(xiàn)了在Web應(yīng)用中對無狀態(tài)會話進行管理,并且該技術(shù)能滿足會話管理在應(yīng)用上的需求。
2 Redis概述
2.1 Redis的特點
Redis是一個以鍵值對為存儲方式的分布式系統(tǒng),同時也是NoSQL 技術(shù)陣營中重要的成員之一。 Redis不僅存儲效率高、支持使用多種不同的數(shù)據(jù)類型、事務(wù)操作是原子性的、還擁有豐富的特性,支持publish/subscribe、通知、key過期等特性[2]。能進一步提高系統(tǒng)數(shù)據(jù)的完整性以及一致性。Redis既有對于不同的常見數(shù)據(jù)類型相同的指令,也有對于不同數(shù)據(jù)類型的特殊指令。此外Jedis是Redis的Java版本客戶端,Jedis可以像Java那樣進行多線程處理,以及使用線程來對系統(tǒng)資源進行優(yōu)化處理,提高系統(tǒng)資源利用率和Redis 的使用效率。在提高數(shù)據(jù)獲取速度時,我們需要用一些緩存技術(shù),Redis的最大優(yōu)勢在于可將數(shù)據(jù)緩存到內(nèi)存并能夠分片存儲,同時擁有很高的讀寫效率[3]。
2.2 Redis的存儲及數(shù)據(jù)恢復(fù)方式
Redis存儲機制的默認(rèn)設(shè)置是:當(dāng)更改了一個Key,那么從更改之時算起,在15分鐘之后Redis進行一次持久化的數(shù)據(jù)存儲操作。當(dāng)更改了十個Key則自修改之時起5分鐘后Redis進行一次持久化的數(shù)據(jù)存儲操作,在完成持久化存儲后,會將臨時文件替換掉之前的RDB文件,完成數(shù)據(jù)的更新。此外,Redis在存儲一些特殊數(shù)據(jù)信息時,如手機號碼、imsi碼等,采用a-z,A-Z,0-9組成的62進制替代10進制可以大大地節(jié)約內(nèi)存,手機號碼可以從11位壓縮到6位,imsi碼可以從15位壓縮到9位[4]。通過這種方式可以進一步壓縮數(shù)據(jù)信息所占用的內(nèi)存。
通過RDB進行數(shù)據(jù)恢復(fù)的方式也很簡單,這里介紹兩種方式:
1)第一種,重啟。只用重新啟動Redis的服務(wù)就可以完成對數(shù)據(jù)的恢復(fù)。因為在啟動時,RedisSever會先從Dump.rdb文件進行數(shù)據(jù)的同步;
2)第二種,利用AOF文件進行恢復(fù)。該方法是記錄下來在Redis服務(wù)中已經(jīng)執(zhí)行過的指令,在進行恢復(fù)數(shù)據(jù)的時候,在AOF文件中按照從前往后的順序?qū)⒅噶钤俅螆?zhí)行一遍以此來達到數(shù)據(jù)恢復(fù)的目的。采用這種方式的優(yōu)點是,能夠更好地保持?jǐn)?shù)據(jù)的完整。采用種方式的缺點是,AOF文件比RDB文件大,并且采用AOF進行數(shù)據(jù)恢復(fù)速度較慢,因為它主要是記錄執(zhí)行過程中的操作指令。
為了能更好地體現(xiàn)出Redis緩存技術(shù)的作用和優(yōu)勢,一般需要在另一個服務(wù)器上搭建一個分布式系統(tǒng)。使用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫遠(yuǎn)遠(yuǎn)不能滿足互聯(lián)網(wǎng)業(yè)務(wù)中存儲大量數(shù)據(jù)的需求。此外,在實際應(yīng)用中,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫不能實時的統(tǒng)計和更新多種不同類型的數(shù)據(jù)資源。因此Redis在分布式系統(tǒng)上搭建好之后可以通過Redis確定各個影響數(shù)據(jù)存儲有效性的影響因素,實現(xiàn)對分布式數(shù)據(jù)的可靠性評測和存儲[5]。
3 Redis會話管理技術(shù)
3.1 有狀態(tài)會話和無狀態(tài)會話概述
平常在進行web開發(fā)時會遇到session,而平常所遇到的這些session統(tǒng)稱為有狀態(tài)session,所謂有狀態(tài)session,就是在一個網(wǎng)站上,用戶進行登錄,登錄成功后就會產(chǎn)生一個會話(session),這時如果有兩個或者更多的用戶來訪問的話就會產(chǎn)生兩個甚至多個的session,如圖1所示,這些session都是用于維護我們系統(tǒng)和用戶之間的會話,建立起連接后,系統(tǒng)可以在不同方法調(diào)用期間保持和維護用戶的狀態(tài),通常對系統(tǒng)的開銷較大。如果會話消失,也就是說用戶沒有訪問我們的網(wǎng)站。當(dāng)用戶下次要再次進行訪問時,或者要再次對網(wǎng)站進行操作時則需要再次進行驗證,只有驗證通過后,才能建立連接。
無狀態(tài)session,就是指用戶在調(diào)用系統(tǒng)中的不同方法時,不會保留任何狀態(tài),當(dāng)然,由于是無狀態(tài)的,所以占用的資源通常較少。假設(shè)有一套系統(tǒng),有用戶進行登錄,但是在登錄之后并沒有將用戶信息存儲到session中去,那么用戶去訪問系統(tǒng)的時候其實是沒有會話的,也就是沒有session這種東西,這時如果有兩個或者更多的用戶來訪問我們這個系統(tǒng)其實都是沒有會話的,那這樣的話,是沒辦法維護系統(tǒng)和用戶之間的關(guān)系,因為用戶訪問一次我們這個系統(tǒng),它的連接就斷開了,當(dāng)下次再要進行訪問時,就必須重新去建立連接。那么這樣子就稱之為無狀態(tài)session。對于無狀態(tài)session,一般來說,我們還是要在后端對它進行一定的控制。
3.2 采用Redis-Session實現(xiàn)無狀態(tài)會話管理分析
欲用一種方式去管理和維護無狀態(tài)Session,既然Web容器也就是tomcat無法去做到的話,那么此時就可以去依靠Redis,也就是一直所談到的緩存。
Redis-Session,當(dāng)App用戶,去訪問這個系統(tǒng)的時候,就會產(chǎn)生一個User-Redis-Session,這樣的一個Session就是把用戶信息,以一個JSON的形式,把整個對象保存到Redis緩存中去就可以了,那么當(dāng)然,緩存和有狀態(tài)session可以說是類似的,是一個鍵值對。另外,對Redis也可以對用戶設(shè)置一定的時間,比如說30分鐘或者一個小時后無操作該User-Redis-Session自動失效。當(dāng)然,當(dāng)有更多的App用戶來訪問系統(tǒng)的時候,所產(chǎn)生的User-Redis-Session會越來越多。如圖2所示。
像這種Redis-Session都可以直接存儲到緩存里面去,不管是單機Redis還是集群Redis,都是沒有問題的。
使用Redis-Session的好處:
1)用戶信息存儲到Redis緩存中,形成無狀態(tài)會話,便于管理。
2)便于擴展,當(dāng)一個單體應(yīng)用擴展成集群的時候會相當(dāng)方便。在我們的集成環(huán)境中,不管我們用戶訪問到我們的哪一節(jié)點,我們的用戶緩存,用戶Session全部都可以被訪問到。這樣就會相當(dāng)方便。
3)便于權(quán)限驗證。如果想獲取到當(dāng)前訪問系統(tǒng)的App用戶信息,則可以在后端設(shè)置一個攔截器,在該攔截器中可以直接獲取到Redis-Session中的用戶信息,從而用于識別該用戶的權(quán)限。
3.3 Redis配置文件編寫
Redis的配置文件信息如圖3所示:
1)redis.hostname:Redis的服務(wù)器地址。這里由于部署Redis時,使用的是另一臺服務(wù)器進行的部署,而這臺服務(wù)器的IP地址是121.199.58.0,所以Redis的服務(wù)器地址就是121.199.58.0。
2)redis.port:Redis的端口號,這里采用的是它默認(rèn)的端口號6379.
3)redis.pool.maxActive:Redis連接池最大能連接的數(shù)量,這里設(shè)置的是100。
4)redis.pool.maxIdle:Redis連接池最大的空閑連接數(shù)量,數(shù)量如果超過最大空閑連接數(shù),則會直接將該對象丟棄。
5)redis.pool.maxWait:Redis連接池最大阻塞等待時間,在建立用戶和Redis之間連接的時候所需要的最大的等待時間,當(dāng)設(shè)置為負(fù)值是,就表示等待的時間無上限。這里設(shè)置的是3000毫秒。
6)redis.pool.testOnBorrow:Borrow一個Jedis實例的時候,是否需要進行alidate操作。這里設(shè)置為true,表示得到的Jedis對象都是可以使用的。
4 Redis實現(xiàn)無狀態(tài)會話管理實驗結(jié)果及分析。
4.1 實驗預(yù)期和結(jié)果分析
用戶在進行登錄時,系統(tǒng)為用戶生成一個唯一的token,同時將用戶的ID作為鍵,token作為值一并存入到redis中,這樣便能建立用戶和系統(tǒng)的聯(lián)系了,同時,當(dāng)系統(tǒng)需要對該用戶的某些權(quán)限時,直接到redis中,通過用戶ID便能直接獲取到用戶的信息。
以下通過采用RedisDesktopManager圖形化Redis管理工具展示實驗結(jié)果:
如圖4所示。
當(dāng)用戶登錄成功時,系統(tǒng)會將用戶的ID作為鍵,也就是圖中的STRING,并將系統(tǒng)為該用戶生成的唯一token(圖中的Value)作為值緩存到redis數(shù)據(jù)庫中。此外,與傳統(tǒng)意義上的有狀態(tài)Session相比較,redis能同時允許多個用戶在同一臺電腦,同一個瀏覽器上進行登錄。因為對于傳統(tǒng)的有狀態(tài)session,一個瀏覽器只能和一個用戶進行連接。當(dāng)多個用戶進行登錄時,后登錄用戶的往往會把之前登錄的用戶的session給替換掉,對于開發(fā)人員,在對不同角色的用戶進行測試時,造成極大不便。當(dāng)采用Redis-Session對用戶的無狀態(tài)會話進行管理時,可以有效地保存用戶的登錄狀態(tài),并且這里同時登錄了兩個賬號,但是并沒有出現(xiàn)被后登錄用戶覆蓋前一個用戶的問題,相比較于有狀態(tài)會話,無狀態(tài)會話所耗費的服務(wù)器資源更少,能顯著地提高系統(tǒng)的性能和用戶體驗感。
4.2 使用無狀態(tài)會話和有狀態(tài)會話性能對比分析
如表1所列,無狀態(tài)會話在多項性能指標(biāo)上優(yōu)于有狀態(tài)會話,但是無狀態(tài)會話并不是適用于所有的場景,當(dāng)出現(xiàn)需要進行頻繁訪問,且訪問之間需要進行一些信息的共享,這個時候就應(yīng)該選擇有狀態(tài)會話。然而,當(dāng)系統(tǒng)中涉及一些不常使用的功能時,無狀態(tài)會話的優(yōu)先級高于有狀態(tài)會話。
5 結(jié)束語
基于Redis的無狀態(tài)會話管理技術(shù)可以有效地管理用戶在訪問系統(tǒng)時所產(chǎn)生的無狀態(tài)會話,并且通過實驗及對比,證實了,無狀態(tài)會話的管理不僅能有效的管理用戶的狀態(tài),且系統(tǒng)開銷小于有狀態(tài)會話,能極大改善系統(tǒng)性能,提高用戶體驗感。
參考文獻:
[1] 陽瑞發(fā).基于攔截器的Web服務(wù)會話技術(shù)研究[J].制造業(yè)自動化,2015,37(20):54-55.
[2] 寧方美,賀雪梅,牟晉娟.SpringBoot集成Redis緩存技術(shù)在企業(yè)一卡通系統(tǒng)中的應(yīng)用[J].電子技術(shù)與軟件工程,2019(24):133-134.
[3] 葉朋.網(wǎng)站訪問性能優(yōu)化的研究與實現(xiàn)[D].哈爾濱:哈爾濱理工大學(xué),2020.
[4] 徐茂紅,王飛,張明.基于大數(shù)據(jù)量的Redis技術(shù)應(yīng)用與研究[J].信息技術(shù)與信息化,2019(11):228-230.
[5] 宋云奎,吳文鵬,趙磊,等.基于Redis的分布式數(shù)據(jù)存儲方法[J].計算機產(chǎn)品與流通,2020(8):106.
【通聯(lián)編輯:謝媛媛】