微服务高并发秒杀实战_基于令牌桶实现库存(1)

@Transactional
public BaseResponse spike(String phone, Long GoodsId) {
GoodsDto goodsDto = seckillMapper.getByGoodsId(GoodsId);
if (goodsDto == null) {
return setResultError(“商品信息不存在!”);
}
// 用户频率限制 setnx 如果key存在话
Boolean reusltNx = redisUtil.setNx(phone, seckillId + “”, 10l);
if (!reusltNx) {
return setResultError(“访问次数过多,10秒后再实现重试!”);// 直接return,无需执行下面的version++操作
}
Long version = goodsDto.getVersion();// 先获取版本号
int row = seckillMapper.inventoryDeduction(GoodsId, version);// 减库存
// 后续可以生成订单到订单表。。。
}



@Component
public class RedisUtil {
@Autowired
private StringRedisTemplate stringRedisTemplate;
// 如果key存在的话返回fasle 不存在的话返回true(原生redis的setNx命令会返回0或1)
public Boolean setNx(String key, String value, Long timeout) {
Boolean setIfAbsent = stringRedisTemplate.opsForValue().setIfAbsent(key, value);
if (timeout != null) {
stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
}
return setIfAbsent;
}

public void setList(String key, List<String> listToken) {
    stringRedisTemplate.opsForList().leftPushAll(key, listToken);
}

}


![](https://img-blog.csdnimg.cn/20190623180802101.png)    ![](https://img-blog.csdnimg.cn/20190623180814293.png)


**3. 基于库存令牌桶 + MQ 实现异步修改库存并提交订单**


在高并发情况下,如果有1万个用户同时秒杀某一商品,对数据库频繁的IO操作,可能会产生数据库崩溃问题(分表分库,读写分离治标不治本),解决方法:基于MQ+库存令牌桶实现。


同时有1万个请求实现秒杀,商品库存只有100个, 实现只需要修改库存100次就可以了:


方案实现流程:商品库存是多少,就提前在redis生成多少对应的库存令牌(这里即为100),在1万个请求中,只要谁能够获取到令牌谁就能够秒杀成功, 获取到秒杀令牌后,在使用mq异步实现修改减去库存。


代码实现:


**① 编写生成100个令牌桶接口**


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值