当前位置:首页 > PHP

php队列实现抢购

2026-02-16 03:33:40PHP

PHP队列实现抢购方案

抢购场景下高并发容易导致超卖、数据库崩溃等问题。使用队列系统能有效缓解压力,以下是基于PHP的常见实现方案:

使用Redis队列

Redis的List结构适合作为轻量级队列,处理抢购请求:

// 初始化Redis连接
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 抢购请求入队
$productId = 1001;
$userId = mt_rand(1000,9999);
$redis->lPush('seckill_queue', json_encode(['user_id'=>$userId, 'product_id'=>$productId]));

// 后台进程消费队列
while(true) {
    $data = $redis->rPop('seckill_queue');
    if($data) {
        $order = json_decode($data, true);
        processOrder($order['user_id'], $order['product_id']);
    }
    usleep(100000); // 0.1秒间隔
}

数据库事务+乐观锁

队列处理后端配合数据库保证数据一致性:

function processOrder($userId, $productId) {
    $pdo->beginTransaction();
    try {
        // 查询库存(加锁)
        $stmt = $pdo->prepare("SELECT stock FROM products WHERE id=? FOR UPDATE");
        $stmt->execute([$productId]);
        $stock = $stmt->fetchColumn();

        if($stock > 0) {
            // 减库存
            $pdo->prepare("UPDATE products SET stock=stock-1 WHERE id=?")->execute([$productId]);
            // 创建订单
            $pdo->prepare("INSERT INTO orders(...) VALUES(...)")->execute([...]);
            $pdo->commit();
            return true;
        }
        $pdo->rollBack();
        return false;
    } catch(Exception $e) {
        $pdo->rollBack();
        return false;
    }
}

使用专业队列系统

对于大规模抢购,建议采用专业队列服务:

  1. RabbitMQ方案
    
    // 生产者
    $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
    $channel = $connection->channel();
    $channel->queue_declare('seckill', false, true, false, false);
    $msg = new AMQPMessage(json_encode($orderData));
    $channel->basic_publish($msg, '', 'seckill');

// 消费者 $callback = function($msg) { processOrder(json_decode($msg->body, true)); $msg->ack(); }; $channel->basic_consume('seckill', '', false, false, false, false, $callback);


2. Kafka方案
```php
$producer = new RdKafka\Producer();
$producer->addBrokers("kafka:9092");
$topic = $producer->newTopic("seckill");
$topic->produce(RD_KAFKA_PARTITION_UA, 0, json_encode($orderData));

预减库存+异步确认

前端展示与实际库存分离的方案:

// 使用Redis原子操作预减库存
$redis->watch('seckill_stock');
$stock = $redis->get('seckill_stock');
if($stock > 0) {
    $redis->multi();
    $redis->decr('seckill_stock');
    $redis->lPush('seckill_queue', $orderData);
    $redis->exec();
    echo '抢购排队中';
} else {
    echo '已售罄';
}

防刷策略

结合队列需要增加安全措施:

  • 用户频率限制(Redis计数器)
  • 验证码验证
  • 排队进度查询接口
  • 订单超时释放库存

这种架构将瞬时高峰请求转为异步处理,数据库压力降低90%以上。实际部署时需要根据业务规模选择合适队列方案,配合负载均衡和多节点部署。

php队列实现抢购

标签: 队列php
分享给朋友:

相关文章

php实现购物车

php实现购物车

PHP实现购物车功能 购物车功能是电商网站的核心模块之一,通常涉及商品添加、删除、数量修改和结算等操作。以下是使用PHP实现购物车功能的几种方法。 使用Session存储购物车数据 Session是…

php实现搜索功能

php实现搜索功能

实现基本的搜索功能 在PHP中实现搜索功能通常涉及数据库查询。以下是一个简单的实现方式,假设使用MySQL数据库: <?php // 连接数据库 $conn = new mysqli('loc…

php 路由实现

php 路由实现

PHP 路由实现方法 在 PHP 中实现路由功能有多种方式,以下是几种常见的实现方法: 使用原生 PHP 实现 通过解析 URL 并匹配对应的控制器和动作: $request = $_SERVER…

php 登录实现

php 登录实现

PHP 登录实现 PHP 登录功能通常包括用户认证、会话管理和安全性措施。以下是实现 PHP 登录功能的关键步骤。 数据库准备 创建一个用户表存储用户信息,通常包括用户名、密码(加密存储)和其他必要…

php实现mysql

php实现mysql

PHP 连接 MySQL 的基本方法 PHP 提供了多种方式与 MySQL 数据库进行交互,以下是最常用的几种方法。 使用 MySQLi 扩展 MySQLi 是 MySQL 的改进扩展,支持面…

php验证码的实现

php验证码的实现

PHP 验证码实现方法 使用 GD 库生成基础验证码 创建画布并生成随机字符串作为验证码内容: session_start(); $width = 120; $height = 40; $image…