1.1 业务背景
随着电子商务的发展,网上购物的用户越来越多,各大网络商家为了达到促销的目的,通常会将一些商品的价格设置为超低的价格,这个时候就导致大量用户前来抢购这一商品。 正式因为这样的促销活动,引发了一次又一次的技术架构革新,并且引起了大量关于解决高并发、高性能、高可用解决方案的讨论。
1.2 秒杀业务存在的挑战
1.2.1 服务的可用性(大量的请求可能会导致应用服务器以及数据库服务负载过重)
1.2.2 数据的一致性和完整性(因为系统需要在一瞬间就处理大量的请求,所以如果稍不谨慎就可能导致数据不一致)
1.2.3 应用的高性能(因为系统需要处理大量的请求,可能会导致请求响应变慢)
1.3 我对秒杀服务的简单设计与猜想
1.3.1 架构设计图
我认为秒杀业务的优化可以从两个大的方面入手:前端的优化、后端的优化(双管齐下)。
1.3.2 前端优化方案
-
前端页面可以做静态化处理,尽量减少一些应用服务器端的动态渲染。
-
通过使用CDN提高页面的响应速度。
-
前端需要控制用户请求的频率,前端可以加入一些比如问答框、对于抢购按钮进行控制。
1.3.3 后端优化方案
-
因抢购商品的用户比较多,所以商品信息查询也是比较频繁的,所以在秒杀开始之前需要将商品信息以及商品的库存信息提前缓存到redis中(如果怕redis宕机可以考虑redis主从配置),这样可以有效的解决数据库压力过大的问题。
-
因后端应用可能有处理请求能力的上线,所以可以通过在nginx、服务网关中加入用户访问限流(常见的限流算法有:令牌桶算法、漏桶算法)
-
关于超卖问题的解决方案,为了解决这一问题,可以通过使用redis的nx与ex指令实现分布式锁或直接使用Redisson快速实现分布式锁,需要注意的是这里可能还有一种情况,就是可能第一个线程进入了分布式锁包围的业务,而这个时候线程被系统调度为阻塞状态,刚好这个时候分布式锁过期了并且第二个线程获取到了一个分布式锁,所以这个时候也可能会有超卖问题的发生,为了解决这个狡猾的问题可以通过redis的exal指令执行lua脚本。
-
在分布式系统中,要保证数据的一致性和完整性可以采用基于消息的最终一致性解决方案