秒杀功能实现 php
秒杀功能实现(PHP)
数据库设计
创建商品表和订单表,商品表需包含库存字段(stock),订单表记录秒杀成功的用户信息。使用事务保证数据一致性。
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`)
);
库存预减
使用Redis预减库存,避免频繁访问数据库。在秒杀开始前将库存加载到Redis中。
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->set('seckill_goods_' . $goodsId, $stock);
乐观锁控制
更新库存时使用乐观锁,通过版本号或条件判断防止超卖。
$pdo->beginTransaction();
$sql = "UPDATE seckill_goods SET stock = stock - 1 WHERE id = ? AND stock > 0";
$stmt = $pdo->prepare($sql);
$stmt->execute([$goodsId]);
if ($stmt->rowCount() > 0) {
// 生成订单
$pdo->commit();
} else {
$pdo->rollBack();
}
接口限流
使用Redis计数器限制用户访问频率,防止恶意请求。
$key = 'seckill_user_' . $userId;
$count = $redis->incr($key);
if ($count == 1) {
$redis->expire($key, 60);
}
if ($count > 10) {
die('请求过于频繁');
}
消息队列异步处理
将秒杀请求放入消息队列,异步处理订单生成,提高系统吞吐量。
$queue = new Redis();
$queue->lPush('seckill_queue', json_encode(['user_id' => $userId, 'goods_id' => $goodsId]));
前端优化
使用倒计时和按钮禁用防止重复提交,秒杀开始前按钮不可点击。
document.getElementById('seckillBtn').disabled = true;
setInterval(function() {
// 倒计时逻辑
}, 1000);
服务器优化
使用Nginx负载均衡和PHP OPcache加速,确保高并发下的性能。配置Nginx限制单个IP的连接数和请求速率。
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_req_zone $binary_remote_addr zone=perreq:10m rate=10r/s;






