美文网首页IT@程序员猿媛
PHP+Redis秒杀其实很简单

PHP+Redis秒杀其实很简单

作者: 祥哥去哪里 | 来源:发表于2019-04-15 22:23 被阅读72次

前言:

秒杀这个问题,一直以来都是经典的面试题。但是秒杀也分大小。如果一个产品的用户不超过5w,上来就问双十一级别的秒杀。那就没有意思了~,所以今天就简单聊下一般条件下的秒杀的思路。方法只有两个,一个是装载秒杀商品。一个就是模拟用户进场秒杀。


PHP+Redis秒杀其实很简单

工具介绍

首先环境就比较简单

  1. Apache
  2. PHP 7.3
  3. redis

框架我选择的ThinkPHP5.1 不过这次我主要还是选择贴近原生的写法

选择apache的原因很简单。自带压力测试工具ab。符合我们的需要。虽然我们知道nginx来做web服务器性能更好。
php7.* 这个不用多介绍了PHP 7 和 PHP 5的性能不是一个世界的
redis 虽然可以实现秒杀的方式有很多。redis算是非常常见的缓存和中间件工具了。在性能和上手难度上都是很不错的选择

一.装载秒杀商品

我们先假设我们有300个人来抢30件商品。那么我们就在我们的商品库里面装载30件不同id的商品
秒杀商品一般都是定时添加的。所以我们需要一个定时任务控制器用cli模式执行

class Crontab
{
      public function addGoods()
    {
        //设定商品数量
        $count=30;
        $listKey="2019_04_15_goods_list";
        //创建连接redis对象
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);
        for ($i=1;$i<=$count;$i++){
            //将商品id push到列表中
            $redis->rPush($listKey,$i);
        }
    }
}

然后当我们需要装载商品的时候我们使用php命令去执行下我们的方法

php /项目地址/public/index.php index/crontab/addgoods

用redis客户端查看下商品id是否放入成功


查看商品id

二.秒杀商品

秒杀商品其实就是一个将集合中的商品id取出和用户id绑定的过程。只是这个过程进行的非常的快。那么我们将秒杀分为两步,如果秒杀成功,则记录下用户id和商品id 也就是所谓的秒杀订单。如果秒杀失败,我们则简单的记录一个秒杀失败的人数。来确定这次秒杀有多少有效用户参与。

  public function kill()
    {
        //假装是用户的唯一标识
        $uuid=md5(uniqid('user').time());
        //创建连接redis对象
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);
        $listKey="2019_04_15_goods_list";
        $orderKey="2019_04_15_buy_order";
        $failUserNum="2019_04_15_fail_user_num";
        if ($goodsId=$redis->lPop($listKey)) {
            //秒杀成功
            //将幸运用户存在集合中
            $redis->hSet($orderKey,$goodsId,$uuid);
        }else{
            //秒杀失败
            //将失败用户计数
            $redis->incr($failUserNum);
        }
        echo "SUCCESS";
    }

压力测试模拟秒杀

刚刚有提到会使用apache自带的ab做测试
小试牛刀 300并发 3000访问量

ab -c 300 -n 3000 http://shop.example.com/index.php/index/index/kill

啥也不说就是干

运行结果

虽说还是比较慢,但是3000次请求,是全部命中没有死掉的用户。加上我本身docker性能没给到最大。加上只有单机节点。我对这个成绩还是比较满意的

下面来看看抢到商品的幸运用户

[root@2f7621a62356 bin]# redis-cli  
127.0.0.1:6379> HGETALL 2019_04_15_buy_order
商品和 用户id的对应关系

再看看秒杀失败的用户数量


抢购失败次数

这时候的商品list已经空空如也了。

好了,今天简单做个秒杀,就介绍到这里。有时候思路比实现的方法更重要。今天我所介绍的主要是一个思路和redis的用法,现实中的秒杀肯定还有很多复杂的逻辑。我也是简单介绍下。如果有什么不对的地方欢迎大神指点。感谢

以上

相关文章

  • PHP+Redis秒杀其实很简单

    前言: 秒杀这个问题,一直以来都是经典的面试题。但是秒杀也分大小。如果一个产品的用户不超过5w,上来就问双十一级别...

  • php+redis 秒杀系统设计

    秒杀问题: 高并发 恶意请求和无效请求 超卖 数据库压力 链接暴露 一、高并发解决方法 用Nginx负载均衡,还可...

  • 秒杀随笔

    方法: mysql悲观锁 mysql乐观锁 PHP+redis分布式锁 PHP+redis乐观锁(redis wa...

  • 倒计时的逻辑和处理时间戳的一些问题

    电商产品中多见于秒杀,抢购,生成订单待付款...等限时倒计时。 倒计时看起来很简单,其实也很简单。 逻辑就是---...

  • 你想不到吧,秒杀系统也有这么多种

    前言 本文结构很简单: 5张图送你5种秒杀系统,再加点骚操作,再顺带些点心里话?‍♀️。 一个简单的秒杀系统 实现...

  • 2022-02-18 亚马逊秒杀活动中途可否调整价格?

    【Update】又做了一次秒杀,发现秒杀中降低价格,似乎是可以的。 其实我之前为了秒杀多出单,是尝试过在秒杀进行中...

  • 其实很简单

    其实很简单(wm197049) 当一个小孩儿认为,他认为的世界是平面的,你千万不要惊讶,更不需要讪笑。这个是真实的...

  • 其实很简单

    有时候女生拒绝你的理由可能很简单 比如,她没洗头,又不好意思说 再比如,你没给对方留下收拾的时间 再比如,你说话的...

  • 其实很简单

    其实人很简单 遇见便已是预见 其实缘分很简单 如山谷中的呐喊 声声皆有回响

  • 其实很简单

    今天,大学室友领证结婚了。相识于今年四月底,男方刚刚分手,加了微信一两天左右在一起,十月领证。原本是关闭了朋友圈的...

网友评论

    本文标题:PHP+Redis秒杀其实很简单

    本文链接:https://www.haomeiwen.com/subject/imbpwqtx.html