当前位置:首页 > PHP

php redis实现秒杀

2026-04-03 02:25:37PHP

使用 PHP 和 Redis 实现秒杀功能

秒杀场景的核心是高并发下的库存控制和防止超卖。Redis 因其高性能和原子操作特性,非常适合实现秒杀系统。

基于 Redis 原子操作实现

使用 Redis 的 DECRINCRBY 命令配合 WATCH 实现原子性库存扣减:

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

$productId = 'product_123';
$userId = uniqid();

// 初始化库存
$redis->set($productId . '_stock', 100);

// 秒杀逻辑
$redis->watch($productId . '_stock');
$stock = $redis->get($productId . '_stock');
if ($stock > 0) {
    $redis->multi();
    $redis->decr($productId . '_stock');
    $result = $redis->exec();
    if ($result) {
        $redis->sAdd($productId . '_success', $userId);
        echo "秒杀成功";
    } else {
        echo "秒杀失败,请重试";
    }
} else {
    $redis->unwatch();
    echo "库存不足";
}

使用 Lua 脚本保证原子性

Lua 脚本在 Redis 中执行是原子的,更适合高并发场景:

$lua = <<<LUA
local stock_key = KEYS[1]
local success_key = KEYS[2]
local user_id = ARGV[1]
local stock = tonumber(redis.call('GET', stock_key))
if stock and stock > 0 then
    redis.call('DECR', stock_key)
    redis.call('SADD', success_key, user_id)
    return 1
end
return 0
LUA;

$result = $redis->eval($lua, [$productId.'_stock', $productId.'_success', $userId], 2);
if ($result) {
    echo "秒杀成功";
} else {
    echo "秒杀失败";
}

防止重复购买

使用 Redis 集合记录成功用户,避免重复购买:

if ($redis->sIsMember($productId.'_success', $userId)) {
    echo "您已经参与过秒杀";
    exit;
}

限流措施

使用 Redis 实现简单限流,控制访问频率:

$ip = $_SERVER['REMOTE_ADDR'];
$key = 'limit:' . $ip;
$limit = 5; // 5次/秒

if ($redis->get($key) >= $limit) {
    echo "访问过于频繁";
    exit;
}

$redis->incr($key);
$redis->expire($key, 1);

异步处理订单

秒杀成功后,将订单信息放入队列异步处理:

if ($result) {
    $orderData = [
        'user_id' => $userId,
        'product_id' => $productId,
        'time' => time()
    ];
    $redis->rPush('order_queue', json_encode($orderData));
}

库存预热

提前将库存加载到 Redis,避免秒杀开始时的数据库压力:

php redis实现秒杀

// 从数据库获取库存
$stockFromDB = 100; // 假设从数据库查询得到
$redis->set($productId.'_stock', $stockFromDB);

注意事项

  1. 使用连接池管理 Redis 连接,避免频繁创建连接
  2. 监控 Redis 性能,确保能够承受预期流量
  3. 考虑使用 Redis 集群提高可用性
  4. 秒杀结束后同步 Redis 和数据库的库存数据
  5. 前端应配合使用验证码、按钮禁用等措施防止重复提交

标签: 秒杀php
分享给朋友:

相关文章

php实现推送

php实现推送

PHP 实现推送功能的方法 PHP 实现推送功能可以通过多种方式完成,包括 WebSocket、Server-Sent Events (SSE)、长轮询或第三方推送服务。以下是几种常见的方法: 使用…

php实现的进度条

php实现的进度条

PHP 实现的进度条方法 在 PHP 中实现进度条通常可以通过命令行脚本(CLI)或 Web 页面两种方式完成。以下是几种常见的实现方法: 命令行进度条 使用 PHP CLI 实现进度条,可以通过不…

无限分类实现 php

无限分类实现 php

无限分类的实现方法 无限分类通常用于构建多层级结构的数据,如商品分类、部门架构等。以下是几种常见的实现方式: 邻接列表模式(Adjacency List) 邻接列表是最简单的实现方式,通过在每个记录…

php实现验证码的识别

php实现验证码的识别

验证码识别的基本方法 验证码识别通常分为手动实现和第三方工具两种方式。手动实现需要图像处理和机器学习知识,而第三方工具则更快捷。 使用Tesseract OCR识别验证码 Tesseract是一个开…

php无法实现的

php无法实现的

PHP 的局限性 PHP 是一种广泛使用的服务器端脚本语言,主要用于 Web 开发。尽管功能强大,但在某些场景下存在局限性。 操作系统级开发 PHP 不适合编写操作系统内核或底层驱动程序。这类任务通…

php 实现 java md5加密

php 实现 java md5加密

PHP 实现 Java MD5 加密 Java 和 PHP 的 MD5 加密结果可能存在差异,主要由于字符编码和输出格式的不同。以下是确保 PHP 与 Java MD5 加密结果一致的方法。 确保字…