ThinkPHP5高并发处理方案详解
ThinkPHP5高并发处理方案详解
高并发概念解析
高并发是指系统在短时间内处理大量请求的能力。当多个用户同时访问系统资源(如数据库)时,如果没有适当的并发控制机制,可能会导致数据不一致、系统响应变慢甚至崩溃等问题。
典型的高并发场景
- 电商秒杀活动
- 票务系统抢票
- 社交网络热点事件
- 在线支付系统
ThinkPHP5高并发解决方案
1. 数据库事务与锁机制
基本事务处理示例
public function handleOrder()
{
Db::startTrans(); // 启动事务
try {
// 业务逻辑处理
$result = $this->processOrder();
if ($result) {
Db::commit(); // 提交事务
return true;
} else {
Db::rollback(); // 回滚事务
return false;
}
} catch (\Exception $e) {
Db::rollback(); // 异常回滚
return false;
}
}
悲观锁实现
public function concurrentProcess()
{
Db::startTrans();
try {
// 使用lock(true)加悲观锁
$data = Db::name('product')
->where('id', 1)
->lock(true)
->find();
if ($data['stock'] > 0) {
$update = Db::name('product')
->where('id', 1)
->dec('stock')
->update();
if ($update) {
Db::commit();
return '购买成功';
}
}
Db::rollback();
return '库存不足';
} catch (\Exception $e) {
Db::rollback();
return '系统繁忙';
}
}
2. 乐观锁实现
public function optimisticLock()
{
// 获取当前版本号
$product = Db::name('product')
->where('id', 1)
->find();
// 模拟业务处理时间
sleep(1);
$result = Db::name('product')
->where('id', 1)
->where('version', $product['version'])
->update([
'stock' => Db::raw('stock-1'),
'version' => Db::raw('version+1')
]);
return $result ? '购买成功' : '请重试';
}
高级并发控制方案
1. Redis队列实现
public function redisQueue()
{
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
// 商品ID和用户ID
$productId = 1;
$userId = session('user_id');
// 加入队列
$result = $redis->lPush('order_queue', json_encode([
'product_id' => $productId,
'user_id' => $userId,
'time' => time()
]));
return $result ? '请求已接收' : '系统繁忙';
}
// 队列处理脚本
public function processQueue()
{
while (true) {
$order = $redis->rPop('order_queue');
if ($order) {
$orderData = json_decode($order, true);
$this->createOrder($orderData);
}
usleep(100000); // 0.1秒间隔
}
}
2. 令牌桶限流算法
public function tokenBucket()
{
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$key = 'api_rate_limit:' . get_client_ip();
$capacity = 100; // 桶容量
$rate = 10; // 每秒生成令牌数
$now = microtime(true);
$tokens = $redis->hGet($key, 'tokens');
$lastTime = $redis->hGet($key, 'last_time');
if (!$tokens) {
$tokens = $capacity;
$redis->hSet($key, 'last_time', $now);
} else {
$delta = $rate * ($now - $lastTime);
$tokens = min($capacity, $tokens + $delta);
$redis->hSet($key, 'last_time', $now);
}
if ($tokens >= 1) {
$redis->hSet($key, 'tokens', $tokens - 1);
return true; // 允许访问
}
return false; // 限流
}
性能测试与优化
AB测试命令详解
# 基本测试命令
ab -n 1000 -c 100 http://example.com/api
# 带POST参数测试
ab -n 1000 -c 100 -p postdata.txt -T 'application/x-www-form-urlencoded' http://example.com/api
# 测试结果关键指标:
# Requests per second: 每秒处理请求数
# Time per request: 每个请求平均耗时
# Failed requests: 失败请求数
测试结果分析
-
无并发控制:
- 数据不一致
- 超卖现象
- 响应时间波动大
-
悲观锁控制:
- 数据一致性高
- 吞吐量降低
- 响应时间增加
-
乐观锁控制:
- 中等吞吐量
- 需要重试机制
- 适合冲突较少场景
-
队列处理:
- 高吞吐量
- 异步处理
- 用户体验需要考虑
最佳实践建议
-
分层设计:
- 前端:静态资源CDN、页面缓存
- 应用层:负载均衡、服务拆分
- 数据层:读写分离、分库分表
-
缓存策略:
// Redis缓存示例 public function getProductInfo($id) { $key = 'product_info:' . $id; $data = Cache::get($key); if (!$data) { $data = Db::name('product')->find($id); Cache::set($key, $data, 3600); // 缓存1小时 } return $data; }
-
数据库优化:
- 添加合适索引
- 避免全表扫描
- 使用连接池
-
服务降级方案:
- 核心功能优先
- 非核心功能可降级
- 友好的降级提示
总结
ThinkPHP5处理高并发需要综合考虑多种技术方案:
- 基础方案:数据库事务+锁机制
- 进阶方案:Redis队列+乐观锁
- 高级方案:分布式锁+服务拆分
- 辅助手段:缓存+限流+降级
实际项目中应根据业务特点选择合适的方案组合,并通过压力测试验证系统承载能力。