首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

购物网站的 redis 相关实现

本文主要内容:

登录cookie

购物车cookie

缓存数据库行

测试

必备知识点:

WEB应用就是通过HTTP协议对网页浏览器发出的请求进行相应的服务器或者服务(Service)。

一个WEB服务器对请求进行响应的典型步骤如下:

服务器对客户端发来的请求(request)进行解析

请求被转发到一个预定义的处理器(handler)

处理器可能会从数据库中取出数据

处理器根据取出的数据对模板(template)进行渲染(rander)

处理器向客户端返回渲染后的内容作为请求的相应

以上展示了典型的web服务器运作方式,这种情况下的web请求是无状态的(stateless),服务器本身不会记住与过往请求有关的任何信息,这使得失效的服务器可以很容易的替换掉。

每当我们登录互联网服务的时候,这些服务都会使用cookie来记录我们的身份。

cookies由少量数据组成,网站要求我们浏览器存储这些数据,并且在每次服务发出请求时再将这些数据传回服务。

对于用来登录的cookie ,有两种常见的方法可以将登录信息存储在cookie里:

签名cookie通常会存储用户名,还有用户ID,用户最后一次登录的时间,以及网站觉得有用的其他信息。

令牌cookie会在cookie里存储一串随机字节作为令牌,服务器可以根据令牌在数据库中查找令牌的拥有者。

签名cookie和令牌cookie的优点和缺点:

因为该网站没有实现签名cookie的需求,所以使用令牌cookie来引用关系型数据库表中负责存储用户登录信息的条目。

除了登录信息,还可以将用户的访问时长和已浏览商品的数量等信息存储到数据库中,有利于更好的像用户推销商品

(1)登录和cookie缓存

使用Redis重新实现登录cookie,取代目前由关系型数据库实现的登录cookie功能。

将使用一个散列来存储登录cookie令牌与与登录用户之间的映射。

需要根据给定的令牌来查找与之对应的用户,并在已经登录的情况下,返回该用户id。

每次用户浏览页面的时候,程序需都会对用户存储在登录散列里面的信息进行更新,并将用户的令牌和当前时间戳添加到记录最近登录用户的集合里。如果用户正在浏览的是一个商品,程序还会将商品添加到记录这个用户最近浏览过的商品有序集合里面。如果记录商品的数量超过25个时,对这个有序集合进行修剪。

存储会话数据所需的内存会随着时间的推移而不断增加,所有我们需要定期清理旧的会话数据。

清理会话的程序由一个循环构成,这个循环每次执行的时候,都会检查存储在最近登录令牌的有序集合的大小。如果有序集合的大小超过了限制,那么程序会从有序集合中移除最多100个最旧的令牌,并从记录用户登录信息的散列里移除被删除令牌对应的用户信息,并对存储了这些用户最近浏览商品记录的有序集合中进行清理。于此相反,如果令牌的数量没有超过限制,那么程序会先休眠一秒,之后在重新进行检查。

(2)使用redis实现购物车

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

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

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

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

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

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

只是比CleanSessionsThread多了一行代码,伪代码如下:

(3)数据行缓存

为了应对促销活动带来的大量负载,需要对数据行进行缓存,具体做法是:

编写一个持续运行的守护进程,让这个函数指定的数据行缓存到redis里面,并不定期的更新。

缓存函数会将数据行编码为JSON字典并存储在Redis字典里。其中数据列的名字会被映射为JSON的字典,而数据行的值则被映射为JSON字典的值。

程序使用两个有序集合来记录应该在何时对缓存进行更新:

第一个为调用有序集合,他的成员为数据行的ID,而分支则是一个时间戳,这个时间戳记录了应该在何时将指定的数据行缓存到Redis里面

第二个有序集合为延时有序集合,他的成员也是数据行的ID,而分值则记录了指定数据行的缓存需要每隔多少秒更新一次。

为了让缓存函数定期的缓存数据行,程序首先需要将hangID和给定的延迟值添加到延迟有序集合里面,然后再将行ID和当前指定的时间戳添加到调度有序集合里面。

通过组合使用调度函数和持续运行缓存函数,实现类一种重读进行调度的自动缓存机制,并且可以随心所欲的控制数据行缓存的更新频率。

如果数据行记录的是特价促销商品的剩余数量,并且参与促销活动的用户特别多的话,那么最好每隔几秒更新一次数据行缓存:另一方面,如果数据并不经常改变,或者商品缺货是可以接受的,那么可以每隔几分钟更新一次缓存。

(4)测试

PS:需要好好补偿英语了!!需要全部的可以到这里下载官方翻译Java版(https://github.com/guoxiaoxu/redis-in-action)

参考

Redis实战(https://www.amazon.cn/dp/B016YLS2LM)

Redis实战相关代码,目前有Java,JS,node,Python(https://github.com/guoxiaoxu/redis-in-action)

2.Redis 命令参考(http://redisdoc.com/index.html)

代码地址:https://github.com/guoxiaoxu/redis_Java

后记

如果你有耐心读到这里,请允许我说明下:

因为技术能力有限,没有梳理清另外两小节,待我在琢磨琢磨。后续补上。

看老外写的书像看故事一样,越看越精彩。不知道你们有这种感觉么?

越学越发现自己需要补充的知识太多了,给我力量吧,欢迎点赞。

感谢所有人,感谢SegmentFault,让你见证我脱变的过程吧。

觉得本文对你有帮助?请分享给更多人。

关注 “程序员宝库”微信公众号,直接获取各种编程资料!

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180301A1FAR100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券