当前位置:首页 > PHP

php 实现抢购

2026-01-29 18:00:12PHP

抢购系统设计要点

抢购系统需要解决高并发、库存超卖、系统稳定性等问题。以下是PHP实现抢购的核心方案:

数据库设计

创建商品表和订单表,商品表需包含库存字段并设置乐观锁:

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `stock` int(11) NOT NULL COMMENT '库存',
  `version` int(11) NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
  PRIMARY KEY (`id`)
);

CREATE TABLE `order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
);

乐观锁实现

通过版本号控制并发更新:

$pdo->beginTransaction();
try {
    // 查询商品信息并锁定行
    $stmt = $pdo->prepare("SELECT stock, version FROM product WHERE id = ? FOR UPDATE");
    $stmt->execute([$productId]);
    $product = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($product['stock'] > 0) {
        // 更新库存
        $update = $pdo->prepare(
            "UPDATE product SET stock = stock - 1, version = version + 1 
             WHERE id = ? AND version = ?"
        );
        $update->execute([$productId, $product['version']]);

        if ($update->rowCount() > 0) {
            // 创建订单
            $pdo->prepare("INSERT INTO `order` (product_id, user_id) VALUES (?, ?)")
                ->execute([$productId, $userId]);
            $pdo->commit();
            return true;
        }
    }
    $pdo->rollBack();
    return false;
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}

缓存预热

使用Redis预存商品库存,避免直接穿透到数据库:

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 活动开始前初始化库存
$redis->set("product_stock_{$productId}", 100);

原子计数器

通过Redis的原子操作保证库存扣减:

$remaining = $redis->decr("product_stock_{$productId}");
if ($remaining >= 0) {
    // 进入订单创建流程
} else {
    // 库存不足
    $redis->incr("product_stock_{$productId}"); // 回滚
}

限流措施

使用Redis实现令牌桶限流:

$rateLimitKey = "rate_limit_{$productId}";
$limit = 100; // 每秒100个请求

if ($redis->exists($rateLimitKey)) {
    $current = $redis->incr($rateLimitKey);
    if ($current > $limit) {
        http_response_code(429);
        exit('Too many requests');
    }
} else {
    $redis->setex($rateLimitKey, 1, 1);
}

异步处理

将订单创建放入消息队列缓解压力:

// 使用RabbitMQ
$connection = new AMQPConnection(['host' => '127.0.0.1']);
$channel = $connection->channel();
$channel->queue_declare('order_queue', false, true, false, false);

$msg = new AMQPMessage(json_encode([
    'product_id' => $productId,
    'user_id' => $userId
]));

$channel->basic_publish($msg, '', 'order_queue');

防机器人脚本

添加验证码机制:

session_start();
if ($_POST['captcha'] !== $_SESSION['captcha']) {
    die('验证码错误');
}

系统监控

实现实时监控关键指标:

php 实现抢购

// 使用Prometheus客户端
$gauge = new Gauge('seckill_requests_total', 'Total requests');
$gauge->inc(); // 请求计数

以上方案需根据实际业务场景调整,测试阶段应进行压力测试验证系统承载能力。分布式环境需考虑使用分布式锁替代单机锁方案。

标签: php
分享给朋友:

相关文章

基于php的设计与实现

基于php的设计与实现

PHP 设计与实现的关键要素 环境搭建与框架选择 PHP开发需配置服务器环境(如Apache/Nginx)、PHP版本(建议7.4+)及数据库(MySQL/MariaDB)。主流框架包括Laravel…

php无限分类的实现

php无限分类的实现

PHP无限分类的实现 无限分类是一种常见的树形结构数据组织方式,适用于商品分类、菜单管理、地区选择等场景。以下是几种实现方法: 递归实现法 递归是最直观的实现方式,通过函数自身调用来遍历子分类。数据…

php怎么实现登录功能

php怎么实现登录功能

数据库准备 创建用户表存储登录信息,通常包括用户名、密码(需加密)等字段。示例SQL: CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY…

php 实现秒杀

php 实现秒杀

PHP 实现秒杀的关键技术 秒杀系统需要解决高并发、超卖、性能瓶颈等问题。以下是实现秒杀的核心方案: 使用 Redis 预减库存 将商品库存提前加载到 Redis 中,通过原子操作保证库存准确性:…

php实现注册登陆

php实现注册登陆

PHP 注册功能实现 创建数据库表结构(MySQL示例): CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, usern…

php实现apk下载

php实现apk下载

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