java秒杀系统设计

1:架构图

java秒杀系统设计

说明:

1:搜索系统主要使用elasticSearch,因为es可以达到PB级别,轻松应对海量数据的查询速度,不建议使用缓存,因为如果商品数据过大,使用缓存占用的容量是非常大,会对缓存这块造成性能影响,而且缓存的搜索方式比较局限

2:用户进来的时候首先通过lvs+nginx+lua脚本判断用户抢购的商品是否是热门商品,,如果是热点数据则走热点数据抢单通道,如果不是热门就走冷门抢购通道

3:热门数据抢购通道使用队列发送到kafka,这样可以避免服务器崩溃

2:淘宝的秒杀架构

java秒杀系统设计

详细设计思路:

秒杀商品一般只会变更库存和价格,不会变更商品的其它属性,可以利用freemarket生成静态页,然后放到cdn服务器中或者使用nginx动静分离。

热点数据是实时更新的,所以会有个汇报功能,用户每次访问商品详情,会垂直收集访问日志,然后发送给kafka集群,记录访问的商品详情和用户以及ip信息,记录ip和用户是为了防止恶意攻击和用户画像

然后通过Apache Druid订阅kafka的数据,实时计算通过druid sql实时分析出哪些商品访问频率过高,哪些ip访问频率过高,可以拦截一些恶意攻击,通过热点分析系统将热点数据存储到redis集群中,因为热点数据毕竟很少。

用户开始抢单,通过lvs+nginx+lua识别用户身份,因为nginx性能好优于java代码,抢购过程中会先通过lua脚本现在redis查询是否存在,如果存在则属于热门商品,然后用户和商品的信息打包发给kafka,此时可以告知用户正在排队

再通过下单系统订阅kafka获取用户和商品信息进行下单,再通过wenSocket+netty通知页面抢单状态。

如何保证热点数据的一致性?再更新热点数据的时候会将商品进行锁定

如果nginx集群宕机了怎么办?

java秒杀系统设计

可以采用Keepalived监控nginx健康状态,会通过选举方式将备用提升为主服务器

如何解决超卖问题?

java秒杀系统设计

因为redis是单线程的,所以并发是安全的,可以通过递减或者递增方式,如果递减后返回为0,则表示该商品已经卖完了