Redis 实现秒杀

时间:2019-10-27 23:55:41

秒杀想必大家都了解,在短时间内请求访问会激增,同时要保证不会超卖和数据的准确,对于技术方面还是有些考验的。可惜的是,一直没有机会在项目中实现。再看了一些资料后,打算实验下。以下代码仅为测试所用,环境比较简单,请根据实际情况进行修改.

直接上代码了。。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

class MiaoshaController extends BaseController{

   public $model;

    private $cache;

    public function init(){

      parent::init();

        $this->cache = new Cache_Redis();

   }

    /**

     * 设置被秒杀的数据

     */

   public function setDataAction(){

        $count = 30;

        $redisKey 'goods_list';

//        echo $this->cache->getLlen($redisKey);exit;

        for ($i = 1; $i <= $count$i++) {

            // 测试用,防止数据错误

            if ($this->cache->getLlen($redisKey) >= $count) {

                break;

            }

            $this->cache->setRpush($redisKey$i);

        }

        //打印设置的结果

        print_r($this->cache->getLrange($redisKey));

   }

    /**

     * 开始秒杀

     */

   public function buyAction(){

        // 随机用户名,无意义,仅做标记

        $username = uniqid('User');

        if ($goodsId $this->cache->getLpop('goods_list')) {

            // 购买成功

            $this->cache->hset('buy_success'$goodsId,$username);

        else {

            // 购买失败

            $this->cache->incr('buy_fail');

        }

   }

    /**

     * 秒杀结果

     */

   public function getBuyDataAction(){

       print_r($this->cache->Hvals('buy_success'));

       echo 'error_num:'.$this->cache->get('buy_fail');

   }

}

redis命名说明:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

/**

    * 在列表中添加一个或多个值

    * @param $key

    * @param $value

    */

public function setRpush($key,$value){

       self::init();

       $key = self::makekey($key);

       self::$redis->rpush($key,$value);

   }

   /**

    * 获取列表长度

    * @param $key

    * @return mixed

    */

   public function getLlen($key){

       self::init();

       $key = self::makekey($key);

       return self::$redis->llen($key);

   }

   /**

    * 获取列表指定范围内的元素

    * 区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。

    * 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推

    * @param $key

    * @param int $start

    * @param int $end

    * @return mixed

    */

   public function getLrange($key,$start=0,$end=-1){

       self::init();

       $key = self::makekey($key);

       return self::$redis->lrange($key,$start,$end);

   }

   /**

    * 移出并获取列表的第一个元素

    * @param $key

    * @return mixed

    */

   public function getLpop($key){

       self::init();

       $key = self::makekey($key);

       return self::$redis->lpop($key);

   }

   /**

    * 将哈希表 key 中的字段 field 的值设为 value 。

    * @param $key

    * @return mixed

    */

   public function hset($key,$field,$value){

       self::init();

       $key = self::makekey($key);

       return self::$redis->hset($key,$field,$value);

   }

   /**

    * 将 key 中储存的数字值增一

    * @param $key

    * @return mixed

    */

   public function incr($key){

       self::init();

       $key = self::makekey($key);

       return self::$redis->incr($key);

   }

   /**

    * 返回哈希表所有域(field)的值。

    * @param $key

    * @return mixed

    */

   public function Hvals($key){

       self::init();

       $key = self::makekey($key);

       return self::$redis->Hvals($key);

   }

第一步设置要秒杀的数据

图片.png

第二步压力测试开始秒杀:

最后就是进行测试了,使用 ab 测试,执行 ab -c 300 -n 3000 http://xxxxxx/miaosha/buy ,上述命令的意思是 300 并发,共请求 3000 次

秒到的结果:

图片.png

图片.png

2976(秒杀失败)+3(请求超时)+30(秒杀到的) = 3000结果正好相符

  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值