Redis緩存和RabbitMQ消息解決購車問題(用戶登錄,用戶未登錄和購物車合併)

在逛各大電商網站的時候,總會有將商品加入購物車,然後合併付款,這個大大的提高了用戶的體驗,某東更是任性,在未登錄的情況下都可以將商品加入購物車,但是任性總是有代價的,後面我會說一下這個小bug。可能不算是個bug,但是體驗上也有不爽的地方。

還是談談購物車是如何實現的吧,購物車首先標識要唯一,因爲每個賬號要對應一個購物車,在登錄狀態下,我們可以直接將數據保存到數據庫中,使用用戶的id表示自己購買的商品,但是如果在未登錄狀態下呢,或者對購車訪問量大的時候,這個就存在弊端,因爲這樣高速的讀寫數據庫,會對數據庫的壓力比較大,在這裏我們就看看如何用RedisRabbitMQ解決這個問題。

第一章:登錄狀態下添加商品到購物車

此時購物車是對應一個用戶,很簡單,就是將商品的數據插入數據庫中即可,但是如果讀寫頻繁的時候,就存在壓力問題,此時我們可以使用Redis擔任讀的部分功能。

在向數據庫中插入數據的時候,使用RabbitMQ發送消息,然後有一個消息系統監聽消息,將RabbitMQ中消息內容(插入數據庫中的商品數據)保存到Redis中,但是此時Redis中我們該用什麼存儲結構,在Redis中存儲結構有很多種,這裏我們使用hash結構,看下面的圖,分析一下hash結構:

 

從上面的圖我們可以看的出來,這個圖有兩個鍵,一個是外部鍵,一個是內部鍵,這個就體現了購物車的好處,這裏外部鍵可以標記一個唯一的購物車,內部鍵就可以標記購物車上的一個商品,一個外部鍵可以對應多個內部鍵,這個和一個購物車裏有多個商品是相符合的,在用戶查詢自己的購物車數據的時候,就不要到數據庫中查詢,而是直接從redis中將數據拿出來即可,這樣數據庫的讀壓力就被Redis分擔出去了。

就這樣把登錄狀態下購物車問題解決了。

第二章:未登錄下加入購物車,登錄下合併購物車

在未登錄狀態下,沒有指定的用戶,此時購物車應該怎麼分配,數據把偶才能在什麼位置,這個其實也不難,我們可以將數據臨時保存到Redis中,並不插入數據庫中,因爲此時沒有對應的用戶,Redis生成一個唯一的outerKey,保存到cookie中,每次添加商品,帶上這個cookie,這樣就保證每次加入同一個購物車,這個數據會被保存一段時間,當用戶登錄的時候,我們該如何將未登錄狀態下的購車和登錄狀態下的購車數據合併呢。這個就需要使用到消息了,我們可以發送一個消息給後臺系統,將未登錄狀態下的outerKey傳遞給後臺系統,後臺系統到Redis中查詢到未登錄狀態下的購物車,將購物車中的數據插入到數據庫中,和之前登錄狀態下的購車數據合併,重新緩存到Redis中,此時緩存到Redis中的購物車是和未登錄狀態不同的,因爲這個緩存的購物車是有主人的,未登錄狀態下緩存的臨時購物車是沒有主人的。

小小bug的解析:

在開頭我們曾說到未登錄狀態下加入臨時購物車,登錄後合併到登錄用戶的購物車中,接下來我看一下這個場景。

小王用小李的電腦逛商城,沒有登錄,將看中的商品加入到了臨時的購物車中,小王還沒有來得及登錄自己的賬號結算購物車,因有事出去了一下,此時小李回來了,他想到之前自己的購物車裏還有商品需要付款,他就毫不猶豫的登錄了自己的賬號,這時候問題來了,小王之前臨時購物車中的商品都會合併到小李的賬戶下,小李的購物車憑空出現自己未加入購物車的商品。過了一會小王回來了,發現自己臨時購物車中的數據都沒有了。這樣是不是就存在用戶體驗的問題,俗稱靈異事件,呵呵,開個玩笑。這種情況就導致了用戶的體驗不好了。

上面的問題我也想過解決方案,但是無果,求各路大神共同解決。

疑問解決:

1、Redis擔任讀的問題,當像雙11這種大量訪問的情況下,Redis會不會崩潰?

這個問題我也想過,這個我們可以考慮使用Redis的集羣,這樣就可以解決大部分的問題。

2、數據庫也可以做讀寫分離,爲什麼要使用Redis擔任讀呢,直接使用讀寫分離不就可以了嗎?

數據庫的讀寫分離的確可以解決問題,但是像Redis這種非關係型數據庫比較明顯的優點就是數據處理效率高,讀寫分離和Redis的效率相比較來說,個人感覺還是使用Redis可靠。

3、在文章中提到RabbitMQ消息機制,這個到底怎麼用?

這個嗎,說來話長,在接下來的博文中我會慢慢的道來RabbitMQ的基本使用和RabbitMQspring的整合。

如果還存在什麼疑問,很歡迎你回覆本帖,大家一起討論。

發佈了44 篇原創文章 · 獲贊 68 · 訪問量 54萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章