商品秒杀php实现
商品秒杀系统设计要点
秒杀系统需要解决高并发、数据一致性、系统稳定性等问题。以下是PHP实现秒杀系统的关键步骤:
数据库设计
创建商品表和订单表,商品表需包含库存字段并设置乐观锁:
CREATE TABLE `seckill_goods` (
`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 `seckill_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`goods_id` int(11) NOT NULL,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
前端优化
静态化秒杀页面,使用CDN加速资源加载。倒计时结束后才显示购买按钮,防止提前请求。通过JavaScript控制按钮状态,避免用户重复提交。

后端逻辑实现
使用Redis预减库存,避免直接访问数据库:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 秒杀开始前将库存加载到Redis
$redis->set('seckill_goods_1_stock', 100);
消息队列处理
使用RabbitMQ或Kafka处理下单请求,实现异步削峰:

// 生产者示例
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$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');
数据库最终一致性
消费者从队列获取消息后处理订单:
// 使用乐观锁更新库存
$pdo->beginTransaction();
$stmt = $pdo->prepare("SELECT stock, version FROM seckill_goods WHERE id = ? FOR UPDATE");
$stmt->execute([$goodsId]);
$goods = $stmt->fetch();
if ($goods['stock'] > 0) {
$update = $pdo->prepare("UPDATE seckill_goods SET stock = stock - 1, version = version + 1
WHERE id = ? AND version = ?");
$affected = $update->execute([$goodsId, $goods['version']]);
if ($affected) {
// 创建订单
$pdo->commit();
return true;
}
}
$pdo->rollBack();
return false;
限流措施
使用Redis实现计数器限流:
$key = 'seckill_user_' . $userId;
$count = $redis->incr($key);
$redis->expire($key, 60);
if ($count > 3) {
die('操作过于频繁');
}
系统监控
实现实时监控系统,关注QPS、库存变化、订单创建成功率等指标。设置阈值报警,及时发现系统异常。
注意事项
测试阶段需模拟高并发场景,验证系统承载能力。上线前进行压力测试,确保各环节无性能瓶颈。定期检查数据库索引和Redis内存使用情况,优化系统性能。






