php秒杀 实现过程
PHP秒杀实现的核心技术
高并发秒杀系统的关键在于解决库存超卖、系统负载和恶意请求问题。以下是实现秒杀功能的核心技术点:
数据库设计优化
创建独立的秒杀商品表,包含商品ID、库存数量、开始时间、结束时间等字段。使用InnoDB引擎并设置合适索引。
CREATE TABLE `seckill_goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`goods_id` int(11) NOT NULL COMMENT '商品ID',
`stock` int(11) NOT NULL COMMENT '库存',
`start_time` datetime NOT NULL COMMENT '开始时间',
`end_time` datetime NOT NULL COMMENT '结束时间',
PRIMARY KEY (`id`),
KEY `idx_time` (`start_time`,`end_time`),
KEY `idx_goods` (`goods_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
库存原子性操作
使用MySQL的乐观锁机制,通过版本号或条件更新保证库存操作的原子性:
// 乐观锁更新
$sql = "UPDATE seckill_goods SET stock = stock - 1 WHERE goods_id = ? AND stock > 0";
$stmt = $pdo->prepare($sql);
$stmt->execute([$goods_id]);
$affected = $stmt->rowCount();
if($affected <= 0) {
// 库存不足处理
}
限流与防刷机制
使用Redis实现计数器限流,防止同一用户重复提交:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$userKey = 'user_limit:'.$user_id;
if($redis->exists($userKey)) {
// 已参与过秒杀
} else {
$redis->setex($userKey, 3600, 1); // 1小时内不能重复参与
}
队列异步处理
使用消息队列削峰填谷,将瞬时高并发请求转为顺序处理:
// 使用Redis列表作为队列
$orderData = [
'user_id' => $user_id,
'goods_id' => $goods_id,
'create_time' => time()
];
$redis->lpush('seckill_queue', json_encode($orderData));
缓存预热与静态化
提前将秒杀商品信息加载到Redis,减少数据库查询:
$goodsInfo = [
'id' => 123,
'name' => '秒杀商品',
'stock' => 100,
'price' => 99
];
$redis->hMSet('seckill_goods:123', $goodsInfo);
系统架构优化
采用分层验证机制:前端按钮置灰→中间层限流→后端队列处理。使用Nginx限速模块和PHP-FPM进程控制防止服务器过载。
# Nginx限速配置
limit_req_zone $binary_remote_addr zone=seckill:10m rate=10r/s;
location /seckill {
limit_req zone=seckill burst=20;
fastcgi_pass 127.0.0.1:9000;
}
分布式锁实现
在集群环境下使用Redis分布式锁防止并发问题:
$lockKey = 'seckill_lock:'.$goods_id;
$randomValue = uniqid();
if ($redis->set($lockKey, $randomValue, ['NX', 'EX' => 10])) {
try {
// 处理秒杀逻辑
} finally {
// Lua脚本保证原子性删除
$script = "
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end";
$redis->eval($script, [$lockKey, $randomValue], 1);
}
}
数据一致性保障
通过定时任务核对Redis缓存与数据库库存,使用事务保证订单创建与库存更新的原子性:

$pdo->beginTransaction();
try {
// 扣减库存
// 创建订单
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
// 异常处理
}






