版权声明:本文为博主原创文章,未经博主允许不得转载。 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 | 获取列表指定范围内的元素 |