ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

健壮的秒杀系统应该考虑哪些问题

2022-02-20 14:32:44  阅读:162  来源: 互联网

标签:健壮 请求 哪些 url redis 秒杀 超卖 stock


这里写目录标题

一:秒杀应该考虑哪些问题

1.1:超卖问题

分析秒杀的业务场景,最重要的有一点就是超卖问题,假如备货只有100个,但是最终超卖了200,一般来讲秒杀系统的价格都比较低,如果超卖将严重影响公司的财产利益,因此首当其冲的就是解决商品的超卖问题。

解决方式

项目肯定是集群部署,扣减库存的逻辑在一段代码中,那么给这段代码加锁。

扣减库存逻辑{
  // 校验库存。查询库存数量是否大于0
  // 扣减库存。 
  // 创建订单
}

1、分布式锁。因为集群部署,所以加的是分布式锁。
2、乐观锁:

------------service层--------------
@Override
public int createOptimisticOrder(int sid) throws Exception {
    //校验库存。 通过商品id查找到当前商品的库存信息(sid、sale、version...)
    Stock stock = checkStock(sid);
    //乐观锁更新库存
    saleStockOptimistic(stock);
    //创建订单
    int id = createOrder(stock);
    return stock.getCount() - (stock.getSale()+1);
}
 
private void saleStockOptimistic(Stock stock) {
    LOGGER.info("查询数据库,尝试更新库存");
    int count = stockService.updateStockByOptimistic(stock);
    if (count == 0){
        throw new RuntimeException("并发更新库存失败,version不匹配") ;
    }
}
---------Mapper------------------------
<update id="updateByOptimistic" parameterType="cn.monitor4all.miaoshadao.dao.Stock">
    update stock
    <set>
      sale = sale + 1,
      version = version + 1,
    </set>
    WHERE id = #{id,jdbcType=INTEGER}
    AND version = #{version,jdbcType=INTEGER}
  </update>

1.2:高并发

秒杀具有时间短、并发量大的特点,秒杀持续时间只有几分钟,而一般公司都为了制造轰动效应,会以极低的价格来吸引用户,因此参与抢购的用户会非常的多。

短时间内会有大量请求涌进来,后端如何防止并发过高造成缓存击穿或者失效,击垮数据库都是需要考虑的问题。

解决方式

1、保证redis高可用。redis集群部署,采用redis-cluster高可用方式;
2、限流。100w的请求量,通过nginx(令牌桶)、histys进行限流,只放20w请求进来;
3、秒杀页面静态化。将商品的描述、参数、成交记录、图像、评价等全部写入到一个静态页面,用户请求不需要通过访问后端服务器,不需要经过数据库,直接在前台客户端生成,这样可以最大可能的减少服务器的压力。具体的方法可以使用freemarker模板技术,建立网页模板,填充数据,然后渲染网页。

1.3:接口防刷

现在的秒杀大多都会出来针对秒杀对应的软件,这类软件会模拟不断向后台服务器发起请求,一秒几百次都是很常见的,如何防止这类软件的重复无效请求,防止不断发起的请求也是需要我们针对性考虑的

解决方式

1、同一个用户xx秒内重复请求直接拒绝。具体的做法就是通过redis的键过期策略,首先对每个请求都从String value = redis.get(userId);如果获取到这个value为空或者为null,表示它是有效的请求,然后放行这个请求。如果不为空表示它是重复性请求,直接丢掉这个请求。如果有效,采用redis.setexpire(userId,value,10).value可以是任意值,一般放业务属性比较好,这个是设置以userId为key,10秒的过期时间(10秒后,key对应的值自动为null)

1.4:秒杀url

对于普通用户来讲,看到的只是一个比较简单的秒杀页面,在未达到规定时间,秒杀按钮是灰色的,一旦到达规定时间,灰色按钮变成可点击状态。这部分是针对小白用户的

如果是稍微有点电脑功底的用户,会通过F12看浏览器的network看到秒杀的url,通过特定软件去请求也可以实现秒杀。

或者提前知道秒杀url的人,一请求就直接实现秒杀了。这个问题我们需要考虑解决。

解决方式

1、将秒杀的url实现动态化。即使是开发整个系统的人都无法在秒杀开始前知道秒杀的url。具体的做法就是通过md5加密一串随机字符作为秒杀的url,然后前端访问后台获取具体的url,后台校验通过之后才可以继续秒杀

1.5:数据库设计

秒杀有把我们服务器击垮的风险,如果让它与我们的其他业务使用在同一个数据库中,耦合在一起,就很有可能牵连和影响其他的业务。
如何防止这类问题发生,就算秒杀发生了宕机、服务器卡死问题,也应该让他尽量不影响线上正常进行的业务。

解决方式

1、应该单独设计一个秒杀数据库,和其他表隔离开,防止因为秒杀活动的高并发访问拖垮整个网站

1.6:大量请求问题

按照1.2的考虑,就算使用缓存还是不足以应对短时间的高并发的流量的冲击。如何承载这样巨大的访问量,同时提供稳定低时延的服务保证,是需要面对的一大挑战。

我们来算一笔账,假如使用的是redis缓存,单台redis服务器可承受的QPS大概是4W左右,如果一个秒杀吸引的用户量足够多的话,单QPS可能达到几十万,单体redis还是不足以支撑如此巨大的请求量。缓存会被击穿,直接渗透到DB,从而击垮mysql。后台会将会大量报错。

参考链接:

系统如何达到秒杀而不被薅羊毛
秒杀系统如何防止超卖?

标签:健壮,请求,哪些,url,redis,秒杀,超卖,stock
来源: https://blog.csdn.net/qq_43783527/article/details/123030572

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有