电商秒杀系统

一,细节

在这里插入图片描述

二,需要注意的细节

1.库存超卖问题
  1. 使用mysql数据库的 悲观锁 机制。在事务中使用 for update 语句,此时数据库会加锁,其他想要当前读的线程都会被阻塞,在事务处理完成之后释放这一条数据。该方法的缺点在于将查询和更新串行化,保证某一时刻只能有一个线程更新数据库。当突然有大量请求后,由于请求串行化,所以大多数线程会因为等待而超时。

public function mysqlLock(){
    $goods_id = 26545;
    $sku_id = 26545;
    $price = 300;
    $user = '';
    StoreOrderModel::startTrans();
    $nums = StoreOrderModel::where(['id'=>1])->field('number')->lock(true)->find();
    $nums = $nums['number'];
    if($nums > 0){
        $item['goods_id'] = $goods_id;
        $item['sku_id'] = $sku_id;
        $item['number'] = $nums;
        $item['price'] = $price;
        $item['user'] = $user;
        $id = StoreModel::insertGetId($item);
        if($id){
            StoreOrderModel::where(['id'=>1])->setDec('number');
            StoreOrderModel::commit();
        }else{
            StoreOrderModel::rollback();
        }
    }else{
        echo "没有库存了";
    }
}
  1. 使用 乐观锁 来实现
    乐观锁一般通过版本号来实现,数据库设计时为每一条记录加一个版本号,通过比较版本号来判断是否有人更新过数据。
    update good set count = count - 1 where id = 1 and version = old_version
    这个办法响应速度快,线程第一步查询时不需要阻塞等待,减少了响应时间。缺点是当同时有大量请求进来时,由于竞争激烈,绝大多数线程都不会更新成功,最终的结果就是虽然用户响应很快,但失败次数多,秒杀后还有很多库存。 最重要的是还需要添加一个version字段,所以一般不使用。
  2. 使用mysql 自身锁 来实现
    利用MySQL自身锁来解决问题,即每次更新前判断扣减库存后是否大于零,大于零时才会进行更新。
    update good set count = count - 1 where id = 1 and count - 1 > 0
    此方法的优点是只需要一次查询,且性能较好。缺点是由于使用了>,所以不会走索引,数据量大时性能不高。
  3. 使用 redis队列 来实现
public function  eq_start(){
 
    $redis = ResRedisModel::getinstance();
    $nums = $redis->lSize('store');
    $goods_id = 26545;
    $sku_id = 26545;
    $number = 1;
    $price = 300;
    $user = '';
 
    if($nums > 0){
        $user = $redis->rPop('store');
        if($user){
            $item['goods_id'] = $goods_id;
            $item['sku_id'] = $sku_id;
            $item['number'] = $number;
            $item['price'] = $price;
            $item['user'] = $user;
            StoreModel::insertGetId($item);
            echo '抢购成功!';
        }else{
            echo '抢购失败!';
        }
    }else{
        echo '抢购失败!';
    }
}
2.限流
  1. nginx配置限流
    令牌桶算法,修改nginx配置文件
http {
    # 根据ip限制速率,zone=名称:(桶)大小,放不下会丢弃请求,rate=同IP 5次/s ,平均200ms/次
	limit_req_zone $binary_remote_addr zone=ratelimit:30m rate=5r/s;
  }
  1. nginx 负载均衡配置,分流到几个服务器
  2. 在代码层面,如框架的中间件中做接口请求限流
3.削峰
  1. 随机拒绝
    假设有100万人来抢购100个商品,既然大部分人都不可能抢到,那我们完全可以在用户提交下单请求时生成一个 0 ~ 100 的随机数,如果这个数大等于 2 则直接告诉用户抢购的人太多请重试,这样能落到 Redis 的请求就只剩下了 2% 也就是 2 万人。在代码层面可以使用路由中间件来实现。

  2. 异步处理
    先判断是否有库存和是否有抢购权限,如果有,立刻返回抢购成功,完成抢购。完成抢购后生成订单等耗时的操作使用rabbitmq等消息中间键做异步队列来执行。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 系统的设计和实现主要包括三个方面:一是系统的架构设计,二是系统的安全性保障,三是系统的数据处理能力。首先,我们需要考虑系统的架构和结构,即系统如何搭建,以及搭建的技术架构。其次,我们要考虑系统安全性保障,其中应包括防止恶意攻击、防止刷抢购等安全措施。最后,我们要考虑的是系统的数据处理能力,包括处理流量、实时监控、数据可视化等。通过上述几方面的考虑,我们可以搭建一个较为完善的系统。 ### 回答2: 系统是一种常见的促销策略,它通过限时限量销售品来吸引消费者。下面是一个系统的设计与实现的简要说明。 首先,系统需要有一个独立的页面或入口,供消费者进入秒活动页面。页面应具备良好的用户体验和界面设计,便于用户浏览和参与秒。 其次,系统需要进行品的预设和准备。在开始秒活动之前,家需要提前确定参与秒品,并且设定品的数量、秒时间和秒价格等信息。在系统中,需要将这些品信息存储和管理。 然后,为了保证秒的公平性和真实性,系统需要进行一定的秒限制。例如,限制用户只能秒一定数量的品,或者设定只有首次登录的用户才能参与秒。还可以考虑引入验证码等措施,防止机器人恶意抢购。 接下来,系统需要实现秒操作的并发控制机制。由于在秒活动中,往往会有大量的用户同时参与抢购,为了保证系统的正常运行和防止超卖等问题,需要考虑如何高效地处理并发请求。可以采用锁机制或者队列机制来达到并发控制的目的。 最后,系统需要进行订单处理和支付的过程。一旦用户秒成功,系统需要生成相应的订单,并提供支付方式供用户完成支付。订单处理过程需要确保数据的一致性和安全性,同时也需要考虑退款和售后等相关问题。 在实现上述功能时,需要充分考虑系统的性能和安全性。例如使用高并发的数据库、分布式缓存等技术,来增强系统的承载能力和抗压能力。此外,还需要注意系统的安全措施,如防止SQL注入、数据加密等。 综上所述,系统的设计与实现涉及到页面设计、品预设、秒限制、并发控制、订单处理和支付等多方面的内容。同时,还需要注重系统的性能和安全性,以提供良好的用户体验和保障消费者的权益。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值