php秒杀实现过程
秒杀系统核心实现要点
高并发秒杀系统的关键在于解决超卖、性能瓶颈和数据一致性。PHP实现需结合缓存、队列和数据库优化。
库存预减与原子操作
使用Redis的DECR原子命令预减库存,避免超卖:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$remaining = $redis->decr('product_123_stock');
if ($remaining < 0) {
$redis->incr('product_123_stock'); // 回滚
die('已售罄');
}
消息队列削峰
将下单请求放入RabbitMQ队列异步处理:
$connection = new AMQPConnection(['host' => '127.0.0.1']);
$channel = $connection->channel();
$channel->queue_declare('seckill_orders', false, true, false, false);
$channel->basic_publish(
new AMQPMessage(json_encode(['user_id' => 1, 'product_id' => 123])),
'',
'seckill_orders'
);
数据库最终一致性
使用事务确保数据完整:
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("UPDATE products SET stock = stock - 1 WHERE id = ? AND stock > 0");
$stmt->execute([123]);
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
}
限流措施
Nginx层限制并发请求:
limit_req_zone $binary_remote_addr zone=seckill:10m rate=10r/s;
location /seckill {
limit_req zone=seckill burst=20 nodelay;
}
缓存预热
提前加载商品数据到Redis:
$product = $db->query("SELECT * FROM products WHERE id = 123")->fetch();
$redis->set('product_123', json_encode($product));
$redis->set('product_123_stock', $product['stock']);
分布式锁防重复
使用Redis SETNX实现分布式锁:
$lockKey = 'seckill_lock_123';
$token = uniqid();
if ($redis->set($lockKey, $token, ['NX', 'EX' => 10])) {
// 处理业务逻辑
$redis->eval("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) end",
[$lockKey, $token], 1);
}






