简单的思路就是:
使用redis的lpush和lpop 在结合查询 lrange 得到目前的数组信息完成需求。
首先给一组固定需要秒杀数量的数据,并设置过期时间。然后根据用户请求,从redis的这个固定数量的数据 一个一个的lpush,然后生成新的关联数据的关系数据,比如 说用户对应的订单,最后通过计算原先数量的数据是否大于1 来判断是否商品被抢光。最后结束活动。
use Illuminate\Support\Facades\Redis;
class RedisController extends Controller
{
public $user_number = 20; // 允许进入队列的人数
public function addStock()
{
$goods_number = 20; // 商品库存数量为10
if (! empty(Redis::llen('goods_name'))) {
echo '已经设置了库存了';
exit;
}
Redis::command('del', ['user_number', 'success']);
// 将商品存入redis链表中
for ($i = 1; $i <= $goods_number; $i++) {
// lpush从链表头部添加元素
Redis::lpush('goods_name', $i);
}
// 设置过期时间
$this->setTime();
// 返回链表 goods_name 的长度
echo '商品存入队列成功,数量:'.Redis::llen('goods_name');
// return view('front.photo');
}
private function setTime()
{
// 设置 goods_name 过期时间,相当于活动时间
Redis::expire('goods_name', 120);
}
public function start()
{
$uid = mt_rand(1, 999); // 假设用户ID
// 如果人数超过50,直接提示被抢完
if (Redis::llen('user_number') > $this->user_number) {
echo '遗憾,被抢完了';
exit;
}
// 获取抢购结果,假设里面存了uid
$result = Redis::lrange('user_number', 0, 20);
// dd($result);
// 如果有一个用户只能抢一次,可以加上下面判断
if (in_array($uid, $result)) {
echo '你已经抢过了';
exit;
}
// 将用户加入队列中
Redis::lpush('user_number', $uid);
// 从链表的头部删除一个元素,返回删除的元素,因为pop操作是原子性,即使很多用户同时到达,也是依次执行
$count = Redis::lpop('goods_name');
if (! $count) {
echo '被抢完了';
exit;
}
$msg = '抢到的人为:'.$uid.',商品ID为:'.$count;
Redis::lpush('success', $msg);
echo '恭喜你,抢到了';
}
/**
* 查看抢到结果
*/
public function result()
{
$result = Redis::lrange('success', 0, 20);
dd($result);
}
ab -n 1000 -c 100 url例如 http://www.baidu.com
-n 1000 总请求数
-c 100 单个时刻并发数

网友评论