当前位置:首页 > 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秒间隔
}

数据库事务+乐观锁

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

php队列实现抢购

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);

php队列实现抢购


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中实现增删改查(CRUD)操作的详细方法,以MySQL数据库为例: 数据库连接配置 创建config.php文件存储数据库连接信息: <?php $host = 'localh…

php长连接实现

php长连接实现

PHP 长连接实现方法 长连接(Keep-Alive)允许客户端与服务器在一次TCP连接中发送和接收多个HTTP请求/响应,减少重复建立连接的开销。以下是PHP中实现长连接的几种方式: 配置HTTP…

php 实现接口

php 实现接口

PHP 实现接口的方法 在 PHP 中,接口(Interface)用于定义一组方法的规范,而不包含具体的实现。类可以实现(implement)接口,并必须实现接口中定义的所有方法。 定义接口 接口通…

php数组实现

php数组实现

PHP 数组的基本实现 PHP 数组是一种非常灵活的数据结构,可以存储多个值,并且支持多种类型的键(整数或字符串)。PHP 数组实际上是有序映射(ordered map),可以看作是列表(vector…

php 实现链表

php 实现链表

PHP 实现链表的方法 链表是一种线性数据结构,由节点组成,每个节点包含数据和指向下一个节点的指针。PHP 中可以通过类和对象来实现链表。 定义链表节点类 创建一个 ListNode 类,用于表示链…

php实现apk下载

php实现apk下载

实现APK下载的PHP代码 创建一个简单的PHP脚本来处理APK文件的下载请求,确保文件传输正确且安全。 <?php $file = 'path/to/your/app.apk'; if (f…