Home Tags Posts tagged with "秒杀"

秒杀

前面的学习中,我们完成了防止超卖商品和抢购接口的限流,已经能够防止大流量把我们的服务器直接搞炸,这篇文章中,我们要开始关心一些细节问题,我们现在设计的系统中还有一些问题

1.我们应该在一定时间内执行秒杀处理,不能在任意时间都接收秒杀请求,如何加入时间验证?

2.对于现有的接口,暴露了我们的接口地址,然后通过脚本抢购怎么办?

3.秒杀开始之后如何限制单个用户的请求频率,即单位时间内的访问次数?

 

此节内容解决:

  • 限时抢购
  • 抢购接口隐藏
  • 单用户限制频率(单位时间内限制访问次数)

 

限时抢购的实现

使用Redis来记录秒杀商品的时间,对秒杀过期的请求进行拒绝处理

 

秒杀请求被拦截:

数据库无改变,即未卖出

Redis 抢购时间可以自己设置,通过传参

通过乐观锁防止超卖+令牌桶限流

 

//开发一个秒杀方法 乐观锁防止超卖,令牌桶限流
@GetMapping("/killtoken")
public  String killtoken(Integer id){
    LOGGER.info("秒杀商品的 ID = " + id);
    //加入令牌桶的限流措施
    //注意:限流之后商品不能百分百的卖掉,有些请求被抛弃,保留一小部分的商品
    if(!rateLimiter.tryAcquire(2,TimeUnit.SECONDS)){
        return "抢购失败,当前秒杀活动过于火爆,请重试!";
    }
    try {//根据秒杀商品的 ID 调用秒杀业务
        int orderId = orderService.kill(id);
        return "秒杀成功!订单ID为:" + orderId;
    }catch (Exception e){
        e.printStackTrace();
        return e.getMessage();
    }
}

会出现商品剩余的情况,因为在接口限流时有一部分请求被抛弃


查看数据库卖出的商品数量:


如果想多卖一点怎么办呢?
1.并发请求加多(Jmeter测试)
2.尝试获取令牌桶的时间+1s
3.增加令牌桶初始大小