当前位置: 首页 > 科技观察

阿里面试的时候,被问到秒杀系统

时间:2023-03-21 14:38:40 科技观察

秒杀活动结构是怎么设计的。秒杀活动是电子商务项目中常见的活动。比如演唱会门票被抢购,京东、淘宝的闪购商品被抢购。在抢购的时刻,会有大量用户同时对应用系统进行高并发请求,可能达到每秒几万、几十万请求。如果系统无法处理如此高的请求,就会崩溃,导致系统不可用。对于秒杀活动,要求系统不会因压力过大而崩溃,不会出现超卖或卖空的情况。因此,在秒杀系统中,我们需要思考:“系统如何处理高并发请求,系统如何保证不超卖?”我对此的解决方案是:“在服务器端,使用缓存减少访问数据库,拦截请求流量上游,可以使用限流技术,使用分布式队列来切流量高峰,序列化并发”秒杀架构图秒杀架构图如上。客户端用户发起请求的端口。目前电商项目秒杀活动的主要客户端包括微信小程序、H5(浏览器)、各平台(Android、iOS、Windows等)APP。我们可以在客户端实现限流机制,防止用户向服务端发送大量请求。客户端的限流可以控制按钮的点击频率,比如将按钮置灰。反向代理我们可以使用Nginx来实现请求分发,通过负载均衡将请求平均分发到不同的web节点。Nginx也可以用作限流器。Nginx可以控制单位时间内的请求数,限制同时连接数。如果实际参与API网关秒杀活动的用户量非常大,那么并发请求量会非常大。我们需要在API网关层面进行限流,可以限制单个Web节点每秒的最大请求数。我们还可以控制每个用户的最大请求数,通过Redis记录每个用户的请求数。缓存属于服务层业务。为了减少对数据库的访问,需要进行缓存设计。我们可以使用本地缓存或分布式缓存。队列队列主要用于实现流量的削峰填谷。我们可以使用RocketMQ、Kafka等消息中间件作为分布式队列。关于限流秒杀系统为什么要限流?秒杀活动中,商品库存有限,用户需求数量远大于商品库存数量。大多数用户请求实际上是无法抓取产品的无效流量。因此,这部分流量可以被拦截并限制上行。为了防止用户使用脚本或者频繁点击发送大量请求,导致其他用户无法正常参与活动,我们还需要控制用户每秒的请求数。我们可以从URI和用户两个方面来实现限流。URI限流示例代码:用户维度限流示例代码:我们获取URI维度的限流器对象uriLimiter和用户维度的userLimiter。如果tryAcquire()成功获取权限,则请求通过,进入后续业务。否则直接报异常,前端界面会给出相应的友好提示。扣除缓存中的库存使用Redis存储库存数量。当用户发起抢购请求时,首先判断Redis中的库存是否可用。如果有,将抢购请求放入分布式队列,异步处理后续操作,完成订单。同时在Redis中进行库存扣减。示例代码如下:先进行库存扣减,获取扣减后的库存数量。如果库存数量大于等于0,则向mq发送订单创建请求。否则返回抓拍失败的信息。消费者创建订单:如何初始化库存?抢购活动开始前,后台有运营人员手动将商品库存从数据库同步到缓存中。库存扣除在缓存中执行。利用Redis的单线程特性,可以实现多线程下的安全库存更新。如果查询时在缓存中没有找到值,则需要从数据库中查询出来,然后同步到缓存中。这个过程需要被锁定。示例代码如下:总结秒杀设计是一个典型的高并发系统,面试中经常会问到秒杀系统的设计。在设计秒杀系统时,需要考虑:“请求导流-通过负载均衡限流-使用漏斗算法(如Guava的RateLimiter)、信号量Semaphore、Redis计数等实现Redis扣库存-减少访问流量到数据库调峰——分布式队列实现》