php中秒杀实现
秒杀系统核心设计要点
高并发、数据一致性、系统稳定性是秒杀系统的核心挑战。PHP实现需结合缓存、队列、限流等技术。
缓存预热与静态化
活动开始前将商品库存加载到Redis,避免直接查询数据库。使用SETNX实现原子操作:
$redis->setnx('seckill:goods:123:stock', 1000);
页面静态化处理,通过CDN分发HTML模板,减少服务端动态渲染压力。
乐观锁控制库存
采用Redis原子操作扣减库存,Lua脚本保证原子性:

local stock = tonumber(redis.call('GET', KEYS[1]))
if stock > 0 then
redis.call('DECR', KEYS[1])
return 1
end
return 0
PHP调用示例:
$script = <<<LUA
-- 上述Lua脚本内容
LUA;
$redis->eval($script, ['seckill:goods:123:stock'], 1);
异步队列处理订单
使用RabbitMQ或Redis List缓冲请求,Worker进程异步创建订单:
// 入队操作
$redis->rpush('seckill:order:queue', json_encode([
'user_id' => 123,
'goods_id' => 456
]));
// Worker消费
while ($data = $redis->blpop('seckill:order:queue', 30)) {
processOrder(json_decode($data[1], true));
}
限流防护措施
Nginx层限流配置:

limit_req_zone $binary_remote_addr zone=seckill:10m rate=100r/s;
location /seckill {
limit_req zone=seckill burst=200 nodelay;
}
PHP令牌桶算法实现:
class RateLimiter {
private $capacity;
private $tokens;
private $lastTime;
public function __construct($capacity) {
$this->capacity = $capacity;
$this->tokens = $capacity;
$this->lastTime = time();
}
public function acquire() {
$now = time();
$elapsed = $now - $this->lastTime;
$this->tokens = min($this->capacity, $this->tokens + $elapsed);
$this->lastTime = $now;
if ($this->tokens < 1) return false;
$this->tokens--;
return true;
}
}
数据一致性保障
采用最终一致性方案,通过定时任务核对Redis与数据库库存差异:
// 核对脚本
$dbStock = getDbStock($goodsId);
$redisStock = $redis->get("seckill:goods:{$goodsId}:stock");
if ($dbStock != $redisStock) {
writeLog("库存不一致: DB{$dbStock} Redis{$redisStock}");
$redis->set("seckill:goods:{$goodsId}:stock", $dbStock);
}
服务降级策略
准备降级开关,当系统压力过大时关闭非核心功能:
if ($cache->get('system:downgrade')) {
return json_encode(['code' => 503, 'msg' => '服务暂时拥挤']);
}
监控系统关键指标(QPS、库存消耗速度、响应时间),设置自动报警阈值。






