php秒杀功能的实现
PHP秒杀功能实现方案
数据库设计
秒杀系统需要高性能数据库设计,核心表包含商品表、订单表和库存表。商品表记录秒杀商品信息,订单表处理交易记录,库存表确保数据一致性。
商品表设计示例:
CREATE TABLE `seckill_goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`stock` int(11) NOT NULL,
`start_time` datetime NOT NULL,
`end_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
缓存预热
使用Redis预加载秒杀商品数据,避免活动开始瞬间数据库压力过大。将商品ID、库存量、开始时间等关键信息存入Redis,采用哈希结构存储。
$redis = new Redis();
$redis->hMSet('seckill:goods:1', [
'stock' => 1000,
'start' => strtotime('2023-06-01 20:00:00')
]);
库存原子操作
通过Redis的DECR原子命令实现库存扣减,确保高并发下的数据一致性。先检查库存再执行扣减,整个过程在Redis中完成。
$remaining = $redis->eval(
"local stock = tonumber(redis.call('HGET', KEYS[1], 'stock'))
if stock <= 0 then return 0 end
redis.call('HINCRBY', KEYS[1], 'stock', -1)
return 1",
['seckill:goods:1'], 1
);
消息队列削峰
使用RabbitMQ或Kafka缓冲瞬时请求,将秒杀请求放入队列异步处理。消费者进程从队列获取请求,完成订单创建和数据库更新。
$channel->queue_declare('seckill_queue', false, true, false, false);
$channel->basic_publish(
new AMQPMessage(json_encode(['user_id' => 123, 'goods_id' => 1])),
'',
'seckill_queue'
);
分布式锁防超卖
采用Redis实现分布式锁,防止集群环境下库存超卖。使用SETNX命令获取锁,设置合理过期时间避免死锁。
$lockKey = 'seckill:lock:goods:1';
$randomValue = uniqid();
if ($redis->set($lockKey, $randomValue, ['NX', 'EX' => 10])) {
try {
// 处理秒杀逻辑
} finally {
$redis->eval(
"if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end",
[$lockKey, $randomValue], 1
);
}
}
接口限流防护
使用令牌桶算法限制访问频率,Nginx层配置限流规则。PHP代码中也可通过Redis实现简单计数器限流。
$key = 'user:123:limit';
$now = microtime(true);
$window = 10; // 10秒窗口
$max = 5; // 最大5次请求
$redis->multi();
$redis->zAdd($key, $now, uniqid());
$redis->zRemRangeByScore($key, 0, $now - $window);
$redis->expire($key, $window);
$count = $redis->exec()[2];
if ($count > $max) {
header('HTTP/1.1 429 Too Many Requests');
exit;
}
数据最终一致性
采用定时任务补偿机制处理异常订单,确保缓存与数据库最终一致。每小时执行一次核对任务,修复数据差异。
// 补偿任务伪代码
$diff = $db->query('SELECT id FROM goods WHERE stock != redis_stock');
foreach ($diff as $item) {
$redis->hSet('seckill:goods:'.$item['id'], 'stock', $item['stock']);
}
性能优化建议
前端实现倒计时和按钮禁用,活动未开始前禁止提交请求。采用CDN加速静态资源,减少服务器负载。
服务端使用OPcache加速PHP执行,配置PHP-FPM合适进程数。数据库添加读写分离,秒杀库单独部署。
压测阶段使用JMeter模拟高并发请求,逐步优化系统瓶颈。监控系统实时关注Redis内存、MySQL QPS等关键指标。







