使用Redis构建Web应用时如何实现购物车?

300 阅读4分钟

网景(Netscape )公司在20世纪90年代中期最先在网络中使用了 cookie,这些cookie最终 变成了我们在上一节讨论的登录会话cookieo cookie最初的意图在于为网络零售商(web retailer ) 提供一种购物车,让用户可以收集他们想要购买的商品。在cookie之前,有过几种不同的购物车 解决方案,但这些方案全都不太好用。

使用cookie实现购物车—— 就是将整个购物车都存储到cookie里面的做法非常常见,这 种做法的一大优点是无须对数据库进行写入就可以实现购物车功能,而缺点则是程序需要重新解 析和验证(validate) cookie,确保cookie的格式正确,并且包含的商品都是真正可购买的商品。 cookie购物车还有一个缺点:因为浏览器每次发送请求都会连cookie一起发送,所以如果购物车 cookie的体积比较大,那么请求发送和处理的速度可能会有所降低。

使用cookie实现购物车——就是将整个购物车都存储到cookie里面。

优点:无需对数据库进行写入就可以实现购物车功能。

缺点:怎是程序需要重新解析和验证cookie,确保cookie的格式正确。并且包含商品可以正常购买。还有一缺点,因为浏览器每次发送请求都会连cookie一起发送,所以如果购物车的体积较大,那么请求发送和处理的速度可能降低。

每个用户的购物车都是一个散列,存储了商品ID与商品订单数量之间的映射。如果用户订购某件商品的数量大于0,那么程序会将这件商品的ID以及用户订购该商品的数量添加到散列里。如果用户购买的商品已经存在于散列里面,那么新的订单数量会覆盖已有的。

相反,如果某用户订购某件商品数量不大于0,那么程序将从散列里移除该条目需要对之前的会话清理函数进行更新,让它在清理会话的同时,将旧会话对应的用户购物车也一并删除。

因为我们在前面已经使用Redis实现了会话cookie和记录用户最近浏览过的商品这两个特 性,所以我们决定将购物车的信息也存储到Redis里面,并且使用与用户会话cookie相同的cookie ID来引用购物车。

购物车的定义非常简单:每个用户的购物车都是一个散列,这个散列存储了商品ID与商品订购 数量之间的映射。对商品数量进行验证的工作由Web应用程序负责,我们要做的则是在商品的订购 数量出现变化时,对购物车进行更新:如果用户订购某件商品的数量大于0,那么程序会将这件商品 的ID以及用户订购该商品的数量添加到散列里面,如果用户购买的商品已经存在于散列里面,那么 新的订购数量会覆盖已有的订购数量;相反地,如果用户订购某件商品的数量不大于0,那么程序将 从散列里面移除该条目。代码清单2-4的add_to_cart()函数展示了程序是如何更新购物车的。

接着,我们需要对之前的会话清理函数进行更新,让它在清理旧会话的同时,将旧会话对应 用户的购物车也一并删除,更新后的函数如下所示。

def clean_full_sessions(conn): while not QUIT:
 size = conn.zcard(1 recent:') if size <= LIMIT:
 time.sleep(1) continue
 
end_index = min(size - LIMIT, 100)
sessions = conn.zrange('recent:1, 0, end_index-l) session_keys =[]
for sess in sessions:
session_keys.append('viewed:' + sess) session_keys.append('cart:' + sess)
conn.delete(*session_keys)
conn.hdel('login:', *sessions) conn.zrem('recent:', *sessions)

新增加的这行代码 用于删除旧会话对应用户的购物车.

我们现在将会话和购物车都存储到了 Redis里面,这种做法除了可以减少请求的体积之外, 还使得我们可以根据用户浏览过的商品、用户放入购物车的商品以及用户最终购买的商品进行统 计计算,并构建起很多大型网络零售商都在提供的“在查看过这件商品的用户当中,有A%的用 户最终购买了这件商品”“购买了这件商品的用户也购买了某某其他商品”等功能,这些功能可 以帮助用户查找其他相关的商品,并最终提升网站的销售业绩。

通过将会话cookie和购物车cookie存储在Redis里面,我们得到了进行数据分析所需的两个重要的数据来源。