流量削峰,利用Redis实现秒杀

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_31617637/article/details/87903202

记录之前做活动时候秒杀优惠券的一些方法,使用Redis的List类型来做队列存储,并利用Redis的高速度,对秒杀时的大量流量进行处理,然后使用处理程序将缓存的结果放置到数据库中。利用内存数据库缓存机制将巨大的流量挡在了数据库之前,有效减少了对服务器I/O的负荷。

时间很久了,记不清源码了,写了个大概,不写怕都要忘记了,o(╥﹏╥)o

秒杀程序

//秒杀优惠券问题接
//接收数据token认证之类的操作
$body = array(
    'couponCode' => 'kjt91000',
    'uid' => 11
);
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redisName = $body['couponCode'];//优惠券编码
//根据业务判断是否可以重复秒杀,如果不可以取出数据去重
$hadSuccessArr = $redis->lRange($redisName,0, $redis->lLen($redisName));//获取已经秒杀到的id信息
foreach ($hadSuccessArr as $hadSuccess){
    //筛选
}

//判断秒杀是否成功
if($redis->decr('secKill') >= 1){//判断用户能否秒杀和抢占秒杀名额,这两个操作必须是原子性的执行
    //秒杀成功
    $redis->rPush($redisName,$uid.'%'.microtime());
    echo $uid.'秒杀成功';
}else{
    echo '秒杀失败';
}

$redis->close();

数据录入

//数据写入库内操作 通过定时任务检索
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redisName = "kjt91000";
$length = $redis->lLen($redisName);
//判断数值是否存在
if($length){
    //从队列最左侧开始取出数值
    $user = $redis->lPop($redisName);
    //切割时间 uid
    $userArr = expload('%', $user);
    $addArr = array(
        'uid' => $userArr[0],
        'time_stamp' => $userArr[1]
    );
    //保存到数据库中
    $res = $db->insert('redis_queue', $addArr);
    //如果失败,数据回滚 将数值重新放到list中
    if(!$res){//可以考虑 try catch 处理
        $redis->rPush($redisName, $user);
    }
}else{
    echo '没有需要插入的数据';
}

//释放redis
$redis->close();

list中常用函数

lPush/lPushx 将数值插入到(/存在的)列表头部
rPush/rPushx 将数值插入到(/存在的)列表尾部
lPop 移除并获取列表的第一个元素
rPop 移除并获取列表的最后一个元素
lTrim 保留指定区间内的元素
lLen 获取列表长度
lSet 通过索引设置列表元素的值
lIndex 通过索引获取列表中的元素
lRange 获取列表指定范围内的元素

猜你喜欢

转载自blog.csdn.net/qq_31617637/article/details/87903202