商品秒杀实现php
商品秒杀系统的核心设计
高并发秒杀系统的关键在于解决超卖问题和性能瓶颈。PHP实现需结合缓存、队列、数据库锁等技术。
数据库设计
创建商品表和订单表是基础。商品表需包含库存字段,订单表记录秒杀成功用户。
CREATE TABLE `seckill_goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) 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`),
UNIQUE KEY `user_goods` (`user_id`,`goods_id`)
);
库存预减机制
使用Redis预减库存避免直接访问数据库。活动开始前将商品库存加载到Redis。
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$stockKey = 'seckill_goods_' . $goodsId;
// 初始化库存
$redis->set($stockKey, 100);
原子性操作
通过Redis的DECR命令保证原子性减库存,Lua脚本实现复杂原子操作。

$script = "
if tonumber(redis.call('get', KEYS[1])) > 0 then
return redis.call('decr', KEYS[1])
else
return -1
end";
$remaining = $redis->eval($script, array($stockKey), 1);
消息队列处理
使用RabbitMQ或Kafka异步处理订单,缓解数据库压力。
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('order_queue', false, true, false, false);
$msg = new AMQPMessage(json_encode(['user_id'=>$userId, 'goods_id'=>$goodsId]));
$channel->basic_publish($msg, '', 'order_queue');
数据库最终一致性
消费者从队列获取消息后完成数据库操作,保证最终一致性。
$callback = function ($msg) {
$data = json_decode($msg->body, true);
// 处理订单入库
$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
};
$channel->basic_consume('order_queue', '', false, false, false, false, $callback);
接口限流措施
使用Redis实现计数器限流,防止系统过载。

$limitKey = 'user_limit_' . $userId;
$limit = $redis->incr($limitKey);
$redis->expire($limitKey, 60);
if ($limit > 5) {
die('请求过于频繁');
}
页面静态化优化
将商品详情页生成静态HTML,减少动态请求。
ob_start();
// 渲染商品页
$content = ob_get_clean();
file_put_contents("seckill_{$goodsId}.html", $content);
分布式锁实现
使用Redis SETNX实现分布式锁,防止重复处理。
$lockKey = 'seckill_lock_' . $goodsId;
$lock = $redis->setnx($lockKey, 1);
if (!$lock && $redis->ttl($lockKey) < 0) {
$redis->expire($lockKey, 10);
}
系统监控告警
实现关键指标监控,如Redis内存、队列积压等。
$queued = $redis->llen('order_queue');
if ($queued > 1000) {
// 触发告警
}






