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