php实现商城秒杀
PHP实现商城秒杀的核心逻辑
商城秒杀的核心在于高并发场景下的库存准确性和系统稳定性。PHP可以通过以下方案实现:
数据库设计
创建秒杀商品表,包含字段如id、name、stock、start_time、end_time。使用InnoDB引擎确保事务支持。
Redis预减库存 在秒杀开始前将库存数量加载到Redis:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->set('seckill_goods_1_stock', 100);
原子性操作 使用Redis的DECR原子操作减少库存:
$remaining = $redis->decr('seckill_goods_1_stock');
if ($remaining < 0) {
$redis->incr('seckill_goods_1_stock'); // 回滚
return '秒杀已结束';
}
消息队列处理订单
RabbitMQ集成 创建生产者将成功请求入队:
$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'=>1, 'goods_id'=>1]));
$channel->basic_publish($msg, '', 'order_queue');
消费者处理 独立进程处理队列消息,确保最终数据库一致性:
$callback = function ($msg) {
$data = json_decode($msg->body, true);
// 数据库事务处理订单
$db->beginTransaction();
try {
$db->query("UPDATE goods SET stock=stock-1 WHERE id={$data['goods_id']}");
$db->query("INSERT INTO orders (...) VALUES (...)");
$db->commit();
} catch (Exception $e) {
$db->rollBack();
}
};
$channel->basic_consume('order_queue', '', false, true, false, false, $callback);
防刷与限流措施
令牌桶限流 使用Redis实现请求限流:
$key = 'user_1_limit';
$redis->multi();
$redis->incr($key);
$redis->expire($key, 10);
if ($redis->exec()[0] > 100) {
die('请求过于频繁');
}
隐藏真实接口 前端通过加密参数访问秒杀接口,例如:
$token = md5($user_id . $goods_id . 'salt');
$url = "/seckill?goods_id=1&token=$token";
系统优化策略
OPcache加速 在php.ini中启用OPcache:
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=4000
Nginx配置优化 设置静态缓存和连接限制:
location ~ \.php$ {
fastcgi_cache seckill_cache;
fastcgi_cache_valid 200 1s;
limit_conn perip 10;
}
数据库优化 添加复合索引并分库分表:
ALTER TABLE `orders` ADD INDEX idx_user_goods (`user_id`,`goods_id`);
实现完整的秒杀系统需要结合压力测试不断调优,建议使用JMeter模拟高并发场景验证系统可靠性。实际部署时应考虑多级缓存策略和分布式架构设计。







