手记

【九月打卡】第7天 --PHP消息队列实现及应用第三章流量削峰案例:Redis的List类型实现秒杀

课程名称:PHP消息队列实现及应用


课程章节:流量削峰案例:Redis的List类型实现秒杀


讲师:Wicon


https://www.imooc.com/video/15163

课程内容:


Redis数据类型中的list类型
1、lpush/lpushx:将值插入到(是否存在)列表头部
2、rpush/rpushx:从尾部插入
3、lpop:移除第一个元素并获取值
4、rpop:移除最后一个元素并获取值
5、ltrim:保留指定区间内元素
6、llen:获取元素长度
7、lset:通过索引设置元素的值

架构设计


秒杀程序实现代码
<?php
//连接本地的 Redis 服务
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

if ($redis) {
    echo "success";
}
$redis_name='miaosha';

for ($i=0; $i<100; $i++) {
    $uid = rand(100000, 9999999);

//接受用户id
   // $uid = $_GET['uid'];
//获取一下redis里面已有的数量
    $num = 10;
//如果当前人数少于时候的时候,则加入这个队列
    if ($redis->lLen($redis_name) < 10) {
        $redis->rPush($redis_name,$uid.'%'.microtime());
        echo $uid . '秒杀成功!'.'<br>';
    } else {
        //如果当天人数已经达到了十个人,则返回秒杀已完成
        echo "秒杀已结束";
    }

}
$redis->close();

?>

服务端:
<?php
include './db.php';
//连接本地的 Redis 服务
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis_name="miaosha";
$db=DB::getIntance();

//死循环,
while (1){
//第一步
//从队列最左侧取出一个值来,
$user = $redis->lPop($redis_name);
//然后判断这个值是否存在,
if(!$user||$user=='nil'){
    sleep(2);
    continue;
}
//如果存在切割出时间,uid
    $user_arr = explode('%', $user);

    $insert_data = array(
        'uid' => $user_arr[0],
        'time_stamp' => $user_arr[1]);


    $res = $db->insert('redis_queue',$insert_data);
//保存数据库中,
  if(!$res){
      $redis->rPush($redis_name,$user);
  }
  sleep(2);
//第二部
//redis如果把值取出来这个值就不在队列里了
//如果出现问题了我的业务没有完成失败的情况下,我们需要有一个备份机制把值重新插回队列里
//数据库插入失败时候的回滚机制
//释放一下redis

}
$redis->close();
?>


课程收获:

这样的秒杀做法可能实际项目中有所不足,我倒是感觉讲师的意思是一种限流的概念,并非是份数的把控,如果需要做到不超卖,还需要再用一个队列对产品的份数进行一个校验。


0人推荐
随时随地看视频
慕课网APP