You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel项目php-fpm CPU占用过高求助,已执行多项优化

问题分析:Laravel测试API高CPU占用排查

问题概况

创建了一个从Redis缓存获取数据的测试API,访问domain/api/test时CPU占用最高达15%。VPS配置为2物理核心+2逻辑核心,已执行Laravel优化(php artisan optimize、优化自动加载)、关闭debug模式、设置APP_ENV=production、安装opcache和apcu,但问题仍存在。

测试路由及CPU占用情况

  • 测试路由1(CPU占用约10%):
Route::get('test', function(){
    return \Cache::remember('test', 6666, function () {
        return \App\Models\ActivityLog::where('id','<',3355)
               ->paginate(20, ['*'], 'page', 2)
               ->toJson();
    });
});
  • 测试路由2(CPU占用9%):
Route::get('test', function(){
    return "string";
});

服务器配置

VPS配置

2 CPU(2物理核心、2逻辑核心)

php-fpm进程状态

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+    COMMAND                                                                    
www       20   0                       S  10.7  3.6     0:49.75  php-fpm   

php-fpm配置

pm = dynamic
pm.status_path = /phpfpm_74_status
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 30

问题排查与解决方案

1. 先明确:当前CPU占用是否属于异常?

你的VPS是2核,单php-fpm进程占用10%左右,换算到单核心是20%左右(总CPU算力为200%),这个数值在Laravel框架的请求处理中不算极端异常——毕竟Laravel作为全栈框架,即使是返回字符串的请求,也需要完成框架初始化、路由匹配、中间件执行、响应处理等一系列流程,这些都会消耗CPU资源。

2. 针对性优化建议

(1)优化php-fpm进程数配置

当前pm.max_children=50对于2核VPS来说过高,过多进程会导致CPU上下文切换频繁,反而增加消耗。建议调整为:

pm.max_children = 8
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4

(2核服务器的pm.max_children一般建议设为核心数的2-4倍,避免进程过多抢占资源)

(2)深度优化Opcache配置

确保Opcache真正生效,检查php.ini中的配置:

opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1

执行php -i | grep opcache确认配置生效,同时通过php-fpm状态页查看Opcache命中率,确保接近100%。

(3)简化路由处理逻辑

即使是测试路由,Laravel默认的全局中间件(比如StartSession、VerifyCsrfToken等)依然会执行。如果是纯API场景,可以:

  • 把测试路由放到api路由文件中,API路由组默认已排除Session、Csrf等不必要的中间件
  • 手动为测试路由移除不需要的中间件:
Route::get('test', function(){
    return "string";
})->withoutMiddleware([
    \App\Http\Middleware\VerifyCsrfToken::class,
    \Illuminate\Session\Middleware\StartSession::class
]);

(4)排查Redis缓存的实际开销

虽然用了Cache::remember,但首次请求会执行数据库查询并序列化存入Redis,后续请求需要从Redis读取并反序列化数据。可以单独测试:

  • 直接返回预生成的JSON字符串(跳过Redis读取),看CPU占用是否下降
  • 检查Redis连接延迟,通过redis-cli ping查看响应时间,确保本地Redis连接稳定

(5)启用PHP的APCu缓存

确保APCu在Laravel中被正确使用,修改config/cache.php:

'array' => [
    'driver' => 'array',
],
'apcu' => [
    'driver' => 'apcu',
],

并将默认缓存驱动临时改为apcu,测试CPU占用是否有变化,排除Redis的额外开销。

3. 性能分析工具定位瓶颈

如果以上优化后仍不满意,可以用工具精准定位:

  • 使用xhprof或tideways分析请求的函数调用耗时,找到CPU消耗最高的环节
  • 使用top -Hp [php-fpm-pid]查看php-fpm进程的线程CPU占用,确认是否有某个线程持续高负载
  • 临时开启Laravel的Query Log,确认数据库查询是否有隐藏开销(即使缓存命中,也要检查是否有意外查询执行)

内容的提问来源于stack exchange,提问作者kennofizet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:00:27