作者:因爱坚持ing来源:苏三说科技
前言:高炳发是如何设计seckill系统的?这是一个频繁的面试问题。这个问题看起来很简单,但里面的水很深。它检查高并发场景中从前端到后端的知识。
secsha通常出现在商场的促销活动中。指定一定数量(如10)的商品(如手机),允许大量用户以非常低的价格(如0.1元)参与活动,但只有少数用户可以成功购买。绝大多数从事此类活动的企业都不赚钱。坦率地说,他们正在寻找一个宣传自己的噱头。
虽然secsha只是一项促销活动,但技术要求并不低。以下总结了设计seckill系统时应注意的9个细节。
1、瞬时高并发一般在第二个杀戮时间点(如12点)前几分钟,用户并发确实会突然增加。当达到第二个终止时间点时,并发性将达到峰值。
然而,由于此类活动是大量用户抢夺少量商品的场景,因此必须有更多的狼和更少的肉。事实上,大多数用户在seckill中都会失败,只有少数用户可以成功。
在正常情况下,大多数用户都会收到货物被盗的提醒。收到提醒后,他们可能不会停留在活动页面上。这样,用户并发性将急剧下降。因此,此峰值的持续时间实际上非常短,这将导致瞬时高并发性。以下是一个图形,可以直观地感受交通量的变化:
传统系统很难处理这种瞬态和高并发场景。我们需要设计一个新的系统。我们可以从以下几个方面入手:
页面静态cdn加速缓存mq异步处理流限制分布式锁2静态活动页面是用户流量的第一个条目,因此它是并发量最大的地方。
如果这些流量可以直接访问服务器,恐怕服务器会挂断,因为它无法承受如此大的压力。
活动页面的大部分内容是固定的,例如:产品名称、产品描述、图片等。为了减少不必要的服务器请求,活动页面通常是静态处理的。用户不会请求服务器进行正常操作,例如浏览商品。只有当达到seckill时间点并且用户主动单击seckill按钮时,才能访问服务器。
这将过滤大多数无效请求。
然而,仅仅使页面保持静态是不够的,因为用户分布在全国各地,有的在北京,有的在成都,有的在深圳。地理差异和网络速度非常不同。
用户如何才能尽快访问活动页面?
这需要使用cdn。它的全称是内容交付网络或内容分发网络。
使用户能够在附近获取所需内容,减少网络拥塞,提高用户访问响应速度和命中率。
3、第二次终止按钮大多数用户害怕错过第二次终止时间点,通常提前进入活动页面。此时您看到的第二个kill按钮是指纹,无法单击。只有在达到第二个终止时间点时,第二个终止按钮才会自动点亮并可单击。
但此时,许多用户都等不及了。通过不断刷新页面,他们努力在第一时间看到第二个kill按钮的灯光。
综上所述,活动页面是静态的。那么,我们如何控制静态页面中的seckill按钮,并且只在seckill时间点点亮它呢?
是的,使用js文件控件。
出于性能原因,静态资源文件(如css、js和图片)通常提前缓存在cdn上,以便用户可以访问附近的seckill页面。
看到这一点,一些聪明的朋友可能会问:cdn上的js文件是如何更新的?
在第二次kill之前,js标志为false,并且还有另一个随机参数。
当第二次kill开始时,系统将生成一个新的js文件。此时,标志为true,将通过随机参数生成一个新值,然后同步到cdn。有了这个随机参数,cdn不会缓存数据,每次都可以从cdn获取最新的js代码。
此外,前端可以添加计时器进行控制,例如,在10秒内只能启动一个请求。如果用户单击第二个kill按钮一次,它将在10秒内变灰,并且不允许再次单击。超过时间限制后,允许再次单击按钮。
4多读少写在seckill过程中,系统一般会检查库存是否充足。如果足够,允许下订单并写入数据库。如果还不够,它会直接退回被抢劫的货物。
由于大量用户抢夺少量商品,只有少数用户可以成功抢夺。因此,当大多数用户在seckill中时,实际上库存不足,系统会直接返回被抢劫的商品。
这是一个非常典型的场景:多读少写。
如果出现成千上万的请求,并且通过数据库检查缓存,则数据库可能会挂起。因为数据库连接资源非常有限,比如mysql,它不能同时支持这么多连接。
相反,应该使用缓存,例如redis。
即使使用redis,也需要部署多个节点。
5缓存问题一般需要在redis中保存商品信息,包括商品id、商品名称、规格属性、库存等信息。同时,数据库中也应该有相关信息。毕竟,缓存并不完全可靠。
在点击seckill按钮请求seckill界面的过程中,用户需要传入商品id参数,然后服务器需要验证商品是否合法。
一般流程如下图所示:
根据产品id,首先从缓存中查询产品。如果产品存在,它将参与第二次杀死。如果不存在,则需要从数据库中查询产品。如果确实存在,则需要将产品信息放入缓存,然后参与第二次销毁。如果产品不存在,则直接提示失败。
这个过程表面上看起来还可以,但如果你深入分析,你会发现一些问题。
5.1缓存崩溃例如,当商品a第一次被杀死时,缓存中没有数据,但数据库中有数据。虽然如果在数据库中找到数据,则有逻辑将其放入缓存。
然而,与此同时,高和将发出大量请求,所有这些都在扼杀同一种商品。这些请求同时检查缓存中是否没有数据,然后同时访问数据库。结果是悲惨的。数据库可能无法承受压力,无法直接挂断。
如何解决这个问题?
这需要锁定。最好使用分布式锁。
当然,在这种情况下,最好在项目开始之前预热缓存。即使首先将所有商品同步到缓存,以便可以直接从缓存中获取商品,也不会出现缓存崩溃。
是否有必要锁定上部?
表面上看,这真的不需要。但是,如果缓存中设置的过期时间不正确,缓存提前过期,或者缓存被意外删除,如果缓存未加速,也可能发生崩溃。
事实上,在这里加锁相当于买保险。
5.2缓存穿透如果缓存或数据库中不存在大量对传入商品id的请求,则这些请求不会每次都通过缓存并直接访问数据库。
由于之前已经添加了锁,即使这里有大量并发,数据库也不会直接挂起。
但显然,这些请求的处理性能并不好。有更好的解决方案吗?
此时,您可以
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件到 quanzhongzhan@qq.com 举报,一经查实,本站将立刻删除。
本文链接:https://www.0771td.com/p/147553.html