Ubuntu 20 VPS上PHP-FPM运行缓慢,该从何处着手优化?
问题描述
在Ubuntu 20系统的VPS上,通过ppa:ondrej/php仓库常规安装了PHP(php-fpm),默认启用Opcache。预期默认原生Laravel页面请求耗时不应超过80ms,但Clockwork统计显示实际耗时超750ms,需定位优化方向。以下是相关配置片段:
APCu Support Enabled Version 5.1.22 APCu Debugging Disabled MMAP Support Enabled MMAP File Mask no value Serialization Support php apc.coredump_unmap Off Off apc.enable_cli Off Off apc.enabled On On apc.entries_hint 4096 4096 apc.gc_ttl 3600 3600 apc.mmap_file_mask no value no value apc.preload_path no value no value apc.serializer php php apc.shm_segments 1 1 apc.shm_size 32M 32M apc.slam_defense Off Off apc.smart 0 0 apc.ttl 0 0 apc.use_request_time Off Off ... Opcode Caching Up and Running Optimization Enabled SHM Cache Enabled File Cache Disabled JIT Disabled Startup OK Shared memory model mmap Cache hits 582 Cache misses 654 Used memory 24600512 Free memory 109617216 Wasted memory 0 Interned Strings Used memory 5320360 Interned Strings Free memory 3068248 Cached scripts 654 Cached keys 1246 Max keys 16229 OOM restarts 0 Hash keys restarts 0 Manual restarts 0 Directive Local Value Master Value opcache.blacklist_filename no value no value opcache.consistency_checks 0 0 opcache.dups_fix Off Off opcache.enable On On opcache.enable_cli Off Off opcache.enable_file_override Off Off opcache.error_log no value no value opcache.file_cache no value no value opcache.file_cache_consistency_checks On On opcache.file_cache_only Off Off opcache.file_update_protection 2 2 opcache.force_restart_timeout 180 180 opcache.huge_code_pages Off Off opcache.interned_strings_buffer 8 8 opcache.jit tracing tracing opcache.jit_bisect_limit 0 0 opcache.jit_blacklist_root_trace 16 16 opcache.jit_blacklist_side_trace 8 8 opcache.jit_buffer_size 0 0 opcache.jit_debug 0 0 opcache.jit_hot_func 127 127 opcache.jit_hot_loop 64 64 opcache.jit_hot_return 8 8 opcache.jit_hot_side_exit 8 8 opcache.jit_max_exit_counters 8192 8192 opcache.jit_max_loop_unrolls 8 8 opcache.jit_max_polymorphic_calls 2 2 opcache.jit_max_recursive_calls 2 2 opcache.jit_max_recursive_returns 2 2 opcache.jit_max_root_traces 1024 1024 opcache.jit_max_side_traces 128 128 opcache.jit_prof_threshold 0.005 0.005 opcache.lockfile_path /tmp /tmp opcache.log_verbosity_level 1 1 opcache.max_accelerated_files 10000 10000 opcache.max_file_size 0 0 opcache.max_wasted_percentage 5 5 opcache.memory_consumption 128 128 opcache.opt_debug_level 0 0 opcache.optimization_level 0x7FFEBFFF 0x7FFEBFFF opcache.preferred_memory_model no value no value opcache.preload no value no value opcache.preload_user no value no value opcache.protect_memory Off Off opcache.record_warnings Off Off opcache.restrict_api no value no value opcache.revalidate_freq 2 2 opcache.revalidate_path Off Off opcache.save_comments On On opcache.use_cwd On On opcache.validate_permission Off Off opcache.validate_root On On opcache.validate_timestamps On On
优化排查步骤
1. 修复Opcache命中率问题
从给出的统计看,缓存命中582、未命中654,命中率仅47%,这是核心性能瓶颈:
- 将
opcache.validate_timestamps设为Off,生产环境下无需频繁校验文件修改时间,部署代码后手动重启php-fpm更新缓存即可。 - 若暂时不想关闭时间校验,把
opcache.revalidate_freq调至300秒以上,减少校验频率。
2. 优化Opcache核心参数
- 启用JIT编译:当前
opcache.jit_buffer_size=0导致JIT禁用,建议设置opcache.jit_buffer_size=64M,保留opcache.jit=tracing模式,PHP 8+的JIT能大幅提升执行速度。 - 扩容缓存文件数:
opcache.max_accelerated_files=10000不足以容纳Laravel项目(含依赖)的文件量,建议调至20000或更高,避免缓存溢出导致频繁淘汰。 - 开启磁盘缓存:设置
opcache.file_cache=/tmp/opcache,让Opcache在内存不足时使用磁盘缓存,且重启php-fpm后能保留缓存,避免重复编译脚本。
3. 优化APCu配置
Laravel默认用APCu缓存配置、路由等数据,调整以下参数:
- 设置
apc.preload_path指向Laravel预加载脚本路径,提前将核心类加载到内存,减少请求时的加载耗时。可通过php artisan optimize生成预加载脚本后配置到php.ini。 - 确认
apc.slam_defense=Off已生效,避免多进程同时缓存同一文件的锁竞争。
4. 调整PHP-FPM进程配置
PHP-FPM进程管理直接影响请求响应速度:
- 根据VPS内存设置
pm.max_children,比如1G内存的VPS设为20左右,避免进程过多耗尽内存触发swap。 - 调整
pm.start_servers、pm.min_spare_servers、pm.max_spare_servers,保持足够空闲进程,避免请求到来时才创建进程的开销。 - 设置合理的
request_terminate_timeout,避免慢请求长期占用进程资源。
5. 系统层面排查
- 用
top/htop查看CPU、内存占用,排查是否有其他进程(如数据库)抢占资源。 - 用
iostat检查磁盘IO性能,若为机械硬盘或IO受限,会拖慢文件加载和缓存读写。 - 在VPS本地执行
curl -w "%{time_total}\n" http://localhost测试耗时,排除网络延迟干扰。
6. Laravel基础优化
- 执行
php artisan optimize:clear清理旧缓存,再运行php artisan optimize生成优化后的配置和路由缓存。 - 确保
APP_ENV=production、APP_DEBUG=false,生产环境下Laravel会关闭调试模式,禁用不必要的错误追踪和日志。 - 检查是否加载了多余的服务提供者或中间件,默认Laravel页面仅需核心组件。
内容的提问来源于stack exchange,提问作者Blum
相关产品推荐
相关产品推荐

