大型商城购物车原理

在逛各大电商网站的时候,总会有将商品加入购物车,而后合并付款,这个大大的提升了用户的体验,某东更是任性,在未登陆的状况下均可以将商品加入购物车,可是任性老是有代价的,后面我会说一下这个小bug。可能不算是个bug,可是体验上也有不爽的地方。redis

仍是谈谈购物车是如何实现的吧,购物车首先标识要惟一,由于每一个帐号要对应一个购物车,在登陆状态下,咱们能够直接将数据保存到数据库中,使用用户的id表示本身购买的商品,可是若是在未登陆状态下呢,或者对购车访问量大的时候,这个就存在弊端,由于这样高速的读写数据库,会对数据库的压力比较大,在这里咱们就看看如何用Redis和RabbitMQ解决这个问题。数据库

第一章:登陆状态下添加商品到购物车缓存

此时购物车是对应一个用户,很简单,就是将商品的数据插入数据库中便可,可是若是读写频繁的时候,就存在压力问题,此时咱们可使用Redis担任读的部分功能。cookie

在向数据库中插入数据的时候,使用RabbitMQ发送消息,而后有一个消息系统监听消息,将RabbitMQ中消息内容(插入数据库中的商品数据)保存到Redis中,可是此时Redis中咱们该用什么存储结构,在Redis中存储结构有不少种,这里咱们使用hash结构,看下面的图,分析一下hash结构:网站

 

从上面的图咱们能够看的出来,这个图有两个键,一个是外部键,一个是内部键,这个就体现了购物车的好处,这里外部键能够标记一个惟一的购物车,内部键就能够标记购物车上的一个商品,一个外部键能够对应多个内部键,这个和一个购物车里有多个商品是相符合的,在用户查询本身的购物车数据的时候,就不要到数据库中查询,而是直接从redis中将数据拿出来便可,这样数据库的读压力就被Redis分担出去了。事件

就这样把登陆状态下购物车问题解决了。hash

第二章:未登陆下加入购物车,登陆下合并购物车it

在未登陆状态下,没有指定的用户,此时购物车应该怎么分配,数据把偶才能在什么位置,这个其实也不难,咱们能够将数据临时保存到Redis中,并不插入数据库中,由于此时没有对应的用户,Redis生成一个惟一的outerKey,保存到cookie中,每次添加商品,带上这个cookie,这样就保证每次加入同一个购物车,这个数据会被保存一段时间,当用户登陆的时候,咱们该如何将未登陆状态下的购车和登陆状态下的购车数据合并呢。这个就须要使用到消息了,咱们能够发送一个消息给后台系统,将未登陆状态下的outerKey传递给后台系统,后台系统到Redis中查询到未登陆状态下的购物车,将购物车中的数据插入到数据库中,和以前登陆状态下的购车数据合并,从新缓存到Redis中,此时缓存到Redis中的购物车是和未登陆状态不一样的,由于这个缓存的购物车是有主人的,未登陆状态下缓存的临时购物车是没有主人的。电商

小小bug的解析:效率

在开头咱们曾说到未登陆状态下加入临时购物车,登陆后合并到登陆用户的购物车中,接下来我看一下这个场景。

小王用小李的电脑逛商城,没有登陆,将看中的商品加入到了临时的购物车中,小王尚未来得及登陆本身的帐号结算购物车,因有事出去了一下,此时小李回来了,他想到以前本身的购物车里还有商品须要付款,他就坚决果断的登陆了本身的帐号,这时候问题来了,小王以前临时购物车中的商品都会合并到小李的帐户下,小李的购物车凭空出现本身未加入购物车的商品。过了一会小王回来了,发现本身临时购物车中的数据都没有了。这样是否是就存在用户体验的问题,俗称灵异事件,呵呵,开个玩笑。这种状况就致使了用户的体验很差了。

上面的问题我也想过解决方案,可是无果,求各路大神共同解决。

疑问解决:

一、Redis担任读的问题,当像双11这种大量访问的状况下,Redis会不会崩溃?

这个问题我也想过,这个咱们能够考虑使用Redis的集群,这样就能够解决大部分的问题。

二、数据库也能够作读写分离,为何要使用Redis担任读呢,直接使用读写分离不就能够了吗?

数据库的读写分离的确能够解决问题,可是像Redis这种非关系型数据库比较明显的优势就是数据处理效率高,读写分离和Redis的效率相比较来讲,我的感受仍是使用Redis可靠。

相关文章
相关标签/搜索