java并发编程的艺术读书笔记(分布式系统架构)

96 阅读4分钟

限流方案

限流算法

令牌桶算法: 1、以固定的速率生成令牌并放入令牌桶,如果令牌桶已满,就直接丢弃这个多余的令牌。 2、当请求到来时,尝试从令牌桶中获取令牌,获取到令牌的请求可以执行,如果桶为空或者获取不到期望数量的令牌,则请求将被丢弃。

基于Redis的分布式限流

基于Sentinel的分布式限流

分布式场景下的秒杀架构方案

需求分析

关键要素:

1、秒杀的峰值TPS是多少。 2、商品的库存是多少。比如我们要在晚上11点秒杀3部手机,峰值流量可能是100000TPS。 3、如何防作弊,如果用户通过作弊工具来秒杀物品,会导致其他人都很难抢到物品,这样影响了秒杀的公平性。

用例分析:

1、查询秒杀活动:用户要查询秒杀活动的基本信息,包括秒杀的物品数量、开始时间、结束时间和秒杀的条件等。
2、发起秒杀请求:秒杀开始后,用户可以发起秒杀请求参与秒杀。
3、接受秒杀成功通知:系统只对秒杀成功的用户发送通知,告诉用户秒杀成功,并在5分钟内完成下单。 4、获得秒杀成功令牌:用户秒杀成功后会获得一个令牌,令牌也被称为Token。 5、下单秒杀商品:用户有了令牌之后,可以对秒杀商品进行下单购买,下单购买成功后令牌失效。 6、超时失效秒杀令牌:如果用户超过五分钟没有使用令牌,令牌会自动失效

秒杀流程图

1、秒杀活动准备:秒杀前用户会不断访问秒杀活动页面,并且重复刷新页面准备秒杀,所以瞬时查询量非常大。当秒杀开始后,系统会将秒杀按钮从不可用状态变为可用状态,然后用户才能开始发起秒杀请求。秒杀开始后可能会触发接口限流,如单机最大QPS是10000,此时系统可以提示用户“参与活动人数太多,请刷新后重试”
2、发起秒杀请求:判断秒杀是否准入,比如同一个ip地址下有大量不同账户在短时间内进行购买,或者同一个账户用多个IP地址发起请求,这种情况,应该把账号加入黑名单,直接拦截后续请求。接着扣减库存,生成秒杀令牌给用户。 3、下单结算:用户持有秒杀令牌之后可以进行购物。系统对令牌进行解密,检查令牌的可用性。可用性包括秒杀商品ID、令牌是否有效和令牌是否过期。如果令牌可用,则允许用户下单,下单成功后删除令牌。

关键设计:库表设计

秒杀系统需要防止超卖现象。出现超卖的原因主要是因为查询和扣减库存这两步操作不是原子的。但是如果秒杀系统和库存系统是两个独立的系统,要保证原子性性能将消耗很大。所以通常做法是在秒杀开始前将库存取出来存放在本地库存队列中,每次秒杀时从本地库存扣减,如果本地没有库存就通知用户秒杀结束,如果秒杀结束之后用户下单失败,再将本地库存归还。

关键设计:秒杀令牌

设计秒杀令牌的好处是将秒杀系统和业务系统做解耦和隔离,因为秒杀系统瞬时请求量非常大,容易出问题,所以,为了避免影响业务系统,如库存和电商系统,必须将秒杀系统独立出来,通过令牌来建立两个系统之间的连接。在秒杀系统中发送令牌给用户,令牌是将用户ID,商品ID和过期时间进行加密,然后在电商系统中验证令牌的有效性,如果有效就允许用户加购物车和下单,下单成功后销毁令牌。

分布式场景下的高并发架构方案