您的位置 首页 golang

win10+php+lua+docker+redis+AB测试,实现商品秒杀代码实现

面试的时候经常会被问到秒杀任务的设计和实现,我之前遇到过很多次,回答得不是很好,我目前在职的公司正好有高并发的项目,所以结合自己公司的项目加上之前面试官问的一些问题。

今天就用实际代码来实现一下秒杀任务简单实现,个人认为掌握这个方法,面试PHP中级,15K-20K基本稳妥的。

开发环境如标题,window10,某个成就1亿人的技术网站调查显示大部分人还是用windows开发。后端语言用的PHP7.3,redis我是用的docker desktop安装的redis6.x,windows本地也能装,因为本地我要安装redis集群,所以就有docker安装redis了,redis6在windows上还不支持集群。

性能测试工具用的AB,服务器上可以用wrk性能测试;好了,这些环境的搭建我就不细说了,初级开发的话这些工具安装应该轻车熟路了。

直接贴代码,展示测试结果:

 <?php
$redis = new \Redis();
$redis->connect('127.0.0.1',6379);
//加锁,分布式锁,设置库存为1000
$redis->setnx('stock',1000);
//模拟用户ID
$user_id = rand(10000,1000000);
//lua脚本,非常简单
$lua = <<<SCRIPT
            local userId   = KEYS[1];
            local goodKey  = KEYS[2];
            local stock    = KEYS[3];
            local userExit = redis.call("sismember",goodKey,userId);
            if tonumber(userExit) == 1 then
                return 2;
            end 
            local num = redis.call("get",stock);
            if tonumber(num) <= 0 then
                return 2;
            else
                redis.call("decr",stock);
                redis.call("sadd",goodKey,userId);
            end 
            return 1;
SCRIPT;
//eval执行lua脚本
$result = $redis->eval($lua,[$user_id,'goods_id','stock'],3);
if ($result == 1) {
    echo '秒杀成功';
} else {
    echo '秒杀失败';
}  

docker中的redis,端口6379,RDM工具可以直接连接到docker中的redis

RDM 连接redis

AB压测工具,压缩包下载放到本地,解压就可以使用,无需安装

cmd进入AB的bin目录,执行命令

ab -n 10000 -c 200 -k “#34;

简单解释下,-n后面参数是请求次数,-c并发数,同时发送请求数,看结果

存了1000个用户id,stock库存为0,没有超卖,符合秒杀要求

再看下压测结果

最重要的参数就是Requests per second 381.8也就是QPS,每秒请求数。个人认为中小公司完全够用了。

当然我这段实例代码是原生的,没有使用框架,生产的秒杀业务不可能这么简单,比如JWT校验,各种规则验证,源于这些会导致接口的性能下降。起码这能解决中小流量的并发抢购,且不超卖业务。

乐观一点说,我这是本地测试,redis用的是虚拟机,相比生产的linux环境或多或少性能要差点。

我司用了redis主从就够了,大公司会用到redis集群,我在docker中也安装了集群。后续我用redis集群来实现秒杀,看看性能。

win10+docker+redis集群

php 操作redis有两种方式,一种是

 <?php
$redis_config = ['127.0.0.1:6379','127.0.0.1:6380','127.0.0.1:6381'];
$redis = new \RedisCluster(null,$redis_config);  

另一种composer安装predis扩展

 <?php

namespace backend\controllers;

use Predis\Client;

class TestController extends BaseController
{
    public function actionIndex()
    {
        $redis_config = [
            'tcp://127.0.0.1:6379',
            'tcp://127.0.0.1.2:6380',
            'tcp://127.0.0.1.3:6381'
        ];

        $redis = new Client($redis_config, ['cluster' => 'redis']);
    }
}  

后续测试下集群秒杀的性能,以及golang实现秒杀,不足之处,请批评指正

文章来源:智云一二三科技

文章标题:win10+php+lua+docker+redis+AB测试,实现商品秒杀代码实现

文章地址:https://www.zhihuclub.com/98886.shtml

关于作者: 智云科技

热门文章

网站地图