产品秒杀php实现
PHP实现秒杀功能的关键技术
秒杀系统需要解决高并发、超卖、性能瓶颈等问题。以下是核心实现方案:
数据库设计
创建秒杀商品表和订单表,商品表需包含库存字段:
CREATE TABLE `seckill_goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`stock` int(11) NOT NULL,
`start_time` datetime NOT NULL,
`end_time` datetime NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `seckill_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`goods_id` int(11) NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
);
悲观锁实现
使用MySQL事务+FOR UPDATE锁定记录:
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("SELECT stock FROM seckill_goods WHERE id = ? FOR UPDATE");
$stmt->execute([$goods_id]);
$stock = $stmt->fetchColumn();
if ($stock > 0) {
$pdo->prepare("UPDATE seckill_goods SET stock = stock - 1 WHERE id = ?")->execute([$goods_id]);
$pdo->prepare("INSERT INTO seckill_orders (...) VALUES (...)")->execute([...]);
$pdo->commit();
} else {
$pdo->rollBack();
}
} catch (Exception $e) {
$pdo->rollBack();
}
乐观锁实现
通过版本号控制并发:
$stmt = $pdo->prepare("UPDATE seckill_goods SET stock = stock - 1, version = version + 1
WHERE id = ? AND stock > 0 AND version = ?");
$affected = $stmt->execute([$goods_id, $version]);
if ($affected > 0) {
// 创建订单
} else {
// 秒杀失败
}
Redis缓存预热
活动开始前将库存加载到Redis:
$redis = new Redis();
$redis->set('seckill:goods:1:stock', 100);
$redis->set('seckill:goods:1:version', 0);
Lua脚本原子操作
使用Redis+Lua保证原子性:
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock > 0 then
redis.call('DECR', KEYS[1])
return 1
else
return 0
end
PHP调用示例:
$script = "..."; // 上面的Lua脚本
$result = $redis->eval($script, ['seckill:goods:1:stock'], 1);
if ($result) {
// 创建订单
}
限流措施
使用Redis实现计数器限流:
$key = 'seckill:user:' . $user_id;
$limit = 1; // 每个用户限购1件
if ($redis->incr($key) > $limit) {
die('超过购买限制');
}
$redis->expire($key, 3600); // 1小时有效期
异步队列处理
使用RabbitMQ缓解数据库压力:
$channel->queue_declare('seckill_queue', false, true, false, false);
$msg = new AMQPMessage(json_encode(['user_id' => 1, 'goods_id' => 1]));
$channel->basic_publish($msg, '', 'seckill_queue');
静态化页面
将活动页生成静态HTML减少服务器负载:
file_put_contents('seckill.html', $rendered_html);
header('Location: /seckill.html');
注意事项
- 前端需添加倒计时和频繁点击限制
- 服务端验证用户身份和购买资格
- 做好压力测试和熔断机制
- 监控系统关键指标如QPS、库存变化
- 考虑分布式锁方案应对集群环境
完整实现需结合具体业务场景调整,建议采用分层架构设计,将库存扣减、订单创建等操作解耦。







