4

基于PHP swoole扩展的秒杀思路

经过ab压力测试,脚本QPS平均值在4500

ab -n1000 -c10 http://127.0.0.1:9501/skill

脚本代码,思路基本上也在代码注释中说明白了

application-Index.php
/**
     * 通过swoole的chan和协程处理秒杀
     * 思路
     * 设置一个通道channel数量为1,一个协程向里面写入用户的数据比如是用户的ID
     * 另一个协程来处理通道的数据写入beanstalkd或者Redis中的队列
     * 此例子我选用写入Redis的list,因为我本机没安装beanstalkd
     */
    public function skill()
    {
        $chan  = new channel(1);
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);

        $res = [];
        //生成者协程
        co::create(function () use ($chan, $redis, &$res) {
            //查看chan中的数量
            $num = $chan->length();
            //当数量等于0并且库存还有的情况下的时候表名,通道为空可以写入数据
            // stock库存需要提前设置到Redis
            if ($num == 0 && $redis->get('stock')) {
                $chan->push(['id' => rand(100, 999)]);
            }
            $res = [0, "抢购失败"];
        });

        //消费者协程
        co::create(function () use ($chan, $redis, &$res) {
            $data = $chan->pop();
            if ($data) {
                //此处默认每个人抢购1件,如果需要抢购多件可以在data中携带购买数量
                //并写入到通道里面
                $redis->set('stock', $redis->get('stock') - 1);
                //写入Redis list 其他脚本进行订单处理之类的IO业务。此处不实现了
                $redis->lPush("skill_swoole", json_encode($data));
                $res = [1, "抢购成功"];
            }
        });

        return Tool::print_json($res[0], $res[1]);

    }

代码仓库

https://github.com/SmallForest/Thomas.kj
这是本人自己写的框架,CLI模式,常驻内存性能高,感兴趣的可以提提建议,帮助一起优化。感谢star

秒杀

秒杀实现方式较多,选择适合自己的最好


SmallForest
239 声望12 粉丝

github: