php redis消息队列 高并发,redis在高并发场景下使用队列实现秒杀功能

秒杀场景一般需要需要解决的问题就是超卖和数据库压力。

一般解决数据库商品超卖最直接的方法就是将字段设置为unsigned(无符号),这样库存就不会为负了。

还有就是可以使用事务锁住操作的行,保证库存。当然也使用锁机制(悲观锁、乐观锁),但是这几种都是直接操作数据库的,并且用锁的话在其他场景(比如不参与抢购原价购买的用户),在高并发场景下可能会造成阻塞,直接影响数据库的性能。

还有种方案就是使用文件排他锁的机制,这里不进行介绍了,有兴趣的可以网上看一下。

redis的list数据结构底层实现就是双端链表,链表中的每个节点都保存了一个整数值。redis链表经常会被用于消息队列的服务,以完成多程序之间的消息交换。链表支持前后插入以及前后取出,所以如果往尾部插入元素,往头部取出元素,实现先进先出,这就是一种消息队列。下来就开始介绍redis中使用list链表实现秒杀的简单消息队列。

以下用到的redis语法简单介绍

LPUSH:将值插入到列表的头部

LPOP:移除并返回列表key的头元素

LLEN:返回列表key的长度

LRANGE:返回列表key中指定区间内的元素

EXPIRE:为key设置生存时间

EXPIREAT:为key设置到期时间

第一步:将参加抢购的商品加入队列<?php

$redis=newRedis();

$redis->connect('127.0.0.1','6379');

// 参加抢购的商品库存

$num=100;

// 将商品写入reids链表

for($i=0;$i

$redis->lpush('goods',1);

}

// 返回链表长度

var_dump($redis->llen('goods'));

// 查看链表中的全部元素

var_dump($redis->lrange('goods',0,-1));

我们可以使用定时任务为redis设置结束时间,或者在抢购方法判断结束时间

// 设置抢购时间为60s

$redis->expire('goods','60');

//设置抢购过期时间为12点 注意expireat方法只能接受时间戳参数

$redis->expireat('goods',strtotime('2019-03-01 12:00:00'));

第二部:下单执行出队列操作<?php

$redis=newRedis();

$redis->connect('127.0.0.1','6379');

//移除链表的头元素 减一次库存

$res=$redis->lPop('goods_store');

if($res){

echo"秒杀成功";

// 执行入库操作

}else{

echo"秒杀结束";

}

使用ab工具模拟高并发下的测试

ab-n1000-c1000http://192.168.73.129/pop.php

高性能系统的优化原则: 写入内存而不是写入硬盘、异步处理而不是同步处理、分布式处理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值