在逛各大電商網站的時候,總會有將商品加入購物車,而後合併付款,這個大大的提升了用戶的體驗,某東更是任性,在未登陸的狀況下均可以將商品加入購物車,可是任性老是有代價的,後面我會說一下這個小bug。可能不算是個bug,可是體驗上也有不爽的地方。redis
仍是談談購物車是如何實現的吧,購物車首先標識要惟一,由於每一個帳號要對應一個購物車,在登陸狀態下,咱們能夠直接將數據保存到數據庫中,使用用戶的id表示本身購買的商品,可是若是在未登陸狀態下呢,或者對購車訪問量大的時候,這個就存在弊端,由於這樣高速的讀寫數據庫,會對數據庫的壓力比較大,在這裏咱們就看看如何用Redis和RabbitMQ解決這個問題。spring
第一章:登陸狀態下添加商品到購物車數據庫
此時購物車是對應一個用戶,很簡單,就是將商品的數據插入數據庫中便可,可是若是讀寫頻繁的時候,就存在壓力問題,此時咱們可使用Redis擔任讀的部分功能。緩存
在向數據庫中插入數據的時候,使用RabbitMQ發送消息,而後有一個消息系統監聽消息,將RabbitMQ中消息內容(插入數據庫中的商品數據)保存到Redis中,可是此時Redis中咱們該用什麼存儲結構,在Redis中存儲結構有不少種,這裏咱們使用hash結構,看下面的圖,分析一下hash結構:cookie
從上面的圖咱們能夠看的出來,這個圖有兩個鍵,一個是外部鍵,一個是內部鍵,這個就體現了購物車的好處,這裏外部鍵能夠標記一個惟一的購物車,內部鍵就能夠標記購物車上的一個商品,一個外部鍵能夠對應多個內部鍵,這個和一個購物車裏有多個商品是相符合的,在用戶查詢本身的購物車數據的時候,就不要到數據庫中查詢,而是直接從redis中將數據拿出來便可,這樣數據庫的讀壓力就被Redis分擔出去了。網站
就這樣把登陸狀態下購物車問題解決了。事件
第二章:未登陸下加入購物車,登陸下合併購物車hash
在未登陸狀態下,沒有指定的用戶,此時購物車應該怎麼分配,數據把偶才能在什麼位置,這個其實也不難,咱們能夠將數據臨時保存到Redis中,並不插入數據庫中,由於此時沒有對應的用戶,Redis生成一個惟一的outerKey,保存到cookie中,每次添加商品,帶上這個cookie,這樣就保證每次加入同一個購物車,這個數據會被保存一段時間,當用戶登陸的時候,咱們該如何將未登陸狀態下的購車和登陸狀態下的購車數據合併呢。這個就須要使用到消息了,咱們能夠發送一個消息給後臺系統,將未登陸狀態下的outerKey傳遞給後臺系統,後臺系統到Redis中查詢到未登陸狀態下的購物車,將購物車中的數據插入到數據庫中,和以前登陸狀態下的購車數據合併,從新緩存到Redis中,此時緩存到Redis中的購物車是和未登陸狀態不一樣的,由於這個緩存的購物車是有主人的,未登陸狀態下緩存的臨時購物車是沒有主人的。it
小小bug的解析:電商
在開頭咱們曾說到未登陸狀態下加入臨時購物車,登陸後合併到登陸用戶的購物車中,接下來我看一下這個場景。
小王用小李的電腦逛商城,沒有登陸,將看中的商品加入到了臨時的購物車中,小王尚未來得及登陸本身的帳號結算購物車,因有事出去了一下,此時小李回來了,他想到以前本身的購物車裏還有商品須要付款,他就堅決果斷的登陸了本身的帳號,這時候問題來了,小王以前臨時購物車中的商品都會合併到小李的帳戶下,小李的購物車憑空出現本身未加入購物車的商品。過了一會小王回來了,發現本身臨時購物車中的數據都沒有了。這樣是否是就存在用戶體驗的問題,俗稱靈異事件,呵呵,開個玩笑。這種狀況就致使了用戶的體驗很差了。
上面的問題我也想過解決方案,可是無果,求各路大神共同解決。
疑問解決:
一、Redis擔任讀的問題,當像雙11這種大量訪問的狀況下,Redis會不會崩潰?
這個問題我也想過,這個咱們能夠考慮使用Redis的集羣,這樣就能夠解決大部分的問題。
二、數據庫也能夠作讀寫分離,爲何要使用Redis擔任讀呢,直接使用讀寫分離不就能夠了嗎?
數據庫的讀寫分離的確能夠解決問題,可是像Redis這種非關係型數據庫比較明顯的優勢就是數據處理效率高,讀寫分離和Redis的效率相比較來講,我的感受仍是使用Redis可靠。
三、在文章中提到RabbitMQ消息機制,這個到底怎麼用?
這個嗎,說來話長,在接下來的博文中我會慢慢的道來RabbitMQ的基本使用和RabbitMQ與spring的整合。
若是還存在什麼疑問,很歡迎你回覆本帖,你們一塊兒討論。