php 抢购实现
抢购系统设计要点
高并发抢购系统的核心在于解决超卖问题、保证数据一致性以及提升系统性能。PHP实现需结合数据库、缓存和队列等技术。
数据库层面优化
使用InnoDB引擎的事务特性确保数据一致性。商品库存字段需设置为无符号整数,避免负数出现。SQL语句示例:
UPDATE products SET stock = stock - 1 WHERE id = ? AND stock >= 1
悲观锁实现方式:
BEGIN;
SELECT * FROM products WHERE id = ? FOR UPDATE;
UPDATE products SET stock = stock - 1 WHERE id = ?;
COMMIT;
Redis缓存层设计
采用Redis原子操作防止超卖。预加载商品库存到Redis,使用DECR命令扣减库存:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$remaining = $redis->decr('product_123_stock');
if ($remaining >= 0) {
// 生成订单
} else {
// 已售罄
}
使用SETNX实现分布式锁:
$lockKey = 'lock_product_123';
$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]) end", [$lockKey, $randomValue], 1);
}
}
消息队列异步处理
使用RabbitMQ或Kafka将订单创建异步化。先快速完成库存扣减,再将订单数据放入队列:

$channel->queue_declare('order_queue', false, true, false, false);
$msg = new AMQPMessage(json_encode($orderData));
$channel->basic_publish($msg, '', 'order_queue');
前端优化策略
实施倒计时同步机制,使用服务端时间而非客户端时间。提交按钮添加防重复点击:
let submitting = false;
function submitOrder() {
if (submitting) return;
submitting = true;
// AJAX请求
}
添加随机延迟提交策略,分散请求峰值:
setTimeout(() => {
submitOrder();
}, Math.random() * 1000);
限流与降级方案
使用Nginx限流模块控制请求频率:
limit_req_zone $binary_remote_addr zone=secburst:10m rate=10r/s;
location /seckill {
limit_req zone=secburst burst=20 nodelay;
}
PHP层实现令牌桶算法:

$rateLimit = new TokenBucket(100, 10); // 容量100,每秒10个
if (!$rateLimit->consume(1)) {
http_response_code(429);
exit;
}
数据预热与缓存策略
活动开始前预热Redis:
$products = $db->query('SELECT id, stock FROM products');
foreach ($products as $product) {
$redis->set("product_{$product['id']}_stock", $product['stock']);
}
采用多级缓存策略,本地缓存+分布式缓存:
$cache = new MultiLevelCache([
new ApcuCache(),
new RedisCache()
]);
$stock = $cache->get("product_{$id}_stock");
监控与报警机制
实施实时监控关键指标:
- Redis内存使用率
- 数据库QPS
- 消息队列堆积量
- 接口响应时间
设置阈值报警,当库存低于5%时触发预警:
if ($redis->get('product_123_stock') < $totalStock * 0.05) {
sendAlert('库存即将售罄');
}






