详解thinkphp+redis+队列的实现代码

2025-05-29 0 38

1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下)

1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图:

详解thinkphp+redis+队列的实现代码  

1.2,php.ini文件新增 extension=php_igbinary.dll;extension=php_redis.dll两处扩展

ok此处已经完成第一步redis环境搭建完成看看phpinfo

详解thinkphp+redis+队列的实现代码

项目中实际使用redis

2.1,第一步配置redis参数如下,redis安装的默认端口为6379: 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
<?php

/* 数据库配置 */

return array(

'data_cache_prefix' => 'redis_',//缓存前缀

'data_cache_type'=>'redis',//默认动态缓存为redis

'data_cache_timeout' => false,

'redis_rw_separate' => true, //redis读写分离 true 开启

'redis_host'=>'127.0.0.1', //redis服务器ip,多台用逗号隔开;读写分离开启时,第一台负责写,其它[随机]负责读;

'redis_port'=>'6379',//端口号

'redis_timeout'=>'300',//超时时间

'redis_persistent'=>false,//是否长连接 false=短连接

'redis_auth'=>'',//auth认证密码

);

?>

2.2,实际函数中使用redis:

?

1

2

3

4

5

6

7

8

9

10

11
/**

* redis连接

* @access private

* @return resource

* @author bieanju

*/

private function connectredis(){

$redis=new \\redis();

$redis->connect(c("redis_host"),c("redis_port"));

return $redis;

}

2.3,秒杀的核心问题是在大并发的情况下不会超出库存的购买,这个就是处理的关键所以思路是第一步在秒杀类的先做一些基础的数据生成:

?

1

2

3

4

5

6

7

8

9

10

11
//现在初始化里面定义后边要使用的redis参数

public function _initialize(){

parent::_initialize();

$goods_id = i("goods_id",'0','intval');

if($goods_id){

$this->goods_id = $goods_id;

$this->user_queue_key = "goods_".$goods_id."_user";//当前商品队列的用户情况

$this->goods_number_key = "goods".$goods_id;//当前商品的库存队列

}

$this->user_id = $this->user_id ? $this->user_id : $_session['uid'];

}

2.4,第二步就是关键所在,用户在进入商品详情页前先将当前商品的库存进行队列存入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
/**

* 访问产品前先将当前产品库存队列

* @access public

* @author bieanju

*/

public function _before_detail(){

$where['goods_id'] = $this->goods_id;

$where['start_time'] = array("lt",time());

$where['end_time'] = array("gt",time());

$goods = m("goods")->where($where)->field('goods_num,start_time,end_time')->find();

!$goods && $this->error("当前秒杀已结束!");

if($goods['goods_num'] > $goods['order_num']){

$redis = $this->connectredis();

$getuserredis = $redis->hgetall("{$this->user_queue_key}");

$gnredis = $redis->llen("{$this->goods_number_key}");

/* 如果没有会员进来队列库存 */

if(!count($getuserredis) && !$gnredis){

for ($i = 0; $i < $goods['goods_num']; $i ++) {

$redis->lpush("{$this->goods_number_key}", 1);

}

}

$resetredis = $redis->llen("{$this->goods_number_key}");

if(!$resetredis){

$this->error("系统繁忙,请稍后抢购!");

}

}else{

$this->error("当前产品已经秒杀完!");

}

}

接下来要做的就是用ajax来异步的处理用户点击购买按钮进行符合条件的数据进入购买的排队队列(如果当前用户没在当前产品用户的队列就进入排队并且pop一个库存队列,如果在就抛出,):

?

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
/**

* 抢购商品前处理当前会员是否进入队列

* @access public

* @author bieanju

*/

public function goods_number_queue(){

!$this->user_id && $this->ajaxreturn(array("status" => "-1","msg" => "请先登录"));

$model = m("flash_sale");

$where['goods_id'] = $this->goods_id;

$goods_info = $model->where($where)->find();

!$goods_info && $this->error("对不起当前商品不存在或已下架!");

/* redis 队列 */

$redis = $this->connectredis();

/* 进入队列 */

$goods_number_key = $redis->llen("{$this->goods_number_key}");

if (!$redis->hget("{$this->user_queue_key}", $this->user_id)) {

$goods_number_key = $redis->lpop("{$this->goods_number_key}");

}

if($goods_number_key){

// 判断用户是否已在队列

if (!$redis->hget("{$this->user_queue_key}", $this->user_id)) {

// 插入抢购用户信息

$userinfo = array(

"user_id" => $this->user_id,

"create_time" => time()

);

$redis->hset("{$this->user_queue_key}", $this->user_id, serialize($userinfo));

$this->ajaxreturn(array("status" => "1"));

}else{

$modelcart = m("cart");

$condition['user_id'] = $this->user_id;

$condition['goods_id'] = $this->goods_id;

$condition['prom_type'] = 1;

$cartlist = $modelcart->where($condition)->count();

if($cartlist > 0){

$this->ajaxreturn(array("status" => "2"));

}else{

$this->ajaxreturn(array("status" => "1"));

}

}

}else{

$this->ajaxreturn(array("status" => "-1","msg" => "系统繁忙,请重试!"));

}

}

附加一个调试的函数,删除指定队列值:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
public function clearredis(){

set_time_limit(0);

$redis = $this->connectredis();

//$rd = $redis->del("{$this->user_queue_key}");

$rd = $redis->hdel("goods49",'用户id'');

$a = $redis->hget("goods_49_user", '用户id');

if(!$a){

dump($a);

}

if($rd == 0){

exit("redis队列已释放!");

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

原文链接:http://blog.csdn.net/weixin_29778143/article/details/54930282

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 详解thinkphp+redis+队列的实现代码 https://www.kuaiidc.com/93910.html

相关文章

发表评论
暂无评论