1. 调整PHP-FPM进程管理参数
进程管理是PHP-FPM性能优化的核心,需根据服务器资源(CPU、内存)和负载特性选择模式并设置合理参数:
static
模式(固定进程数),适合负载稳定的场景,避免动态模式的进程频繁创建/销毁开销;若负载波动大,可使用dynamic
(动态调整)或ondemand
(按需创建)模式。static
模式为例): pm.max_children
:设置为CPU核心数的4-8倍(如4核CPU设为16-32),需确保不超过服务器内存容量(每个进程约占用10-30MB内存,需预留系统和其他服务的内存);pm.start_servers
:设为pm.max_children
的1/4-1/2(如16个max_children
则设为4-8),保证启动时有足够进程处理初始请求;pm.min_spare_servers
/pm.max_spare_servers
:分别设置为pm.start_servers
的1-2倍(如4-8),维持空闲进程池,避免突发请求时进程创建延迟。2. 启用并优化OPcache加速
OPcache可缓存PHP脚本编译后的字节码,避免重复解析,显著提升执行效率:
php.ini
中启用OPcache:zend_extension=opcache.so opcache.enable=1 opcache.memory_consumption=128 # 缓存内存大小(MB),根据脚本数量调整(如128MB可缓存约4000个文件) opcache.interned_strings_buffer=8 # 内部字符串缓冲区大小(MB) opcache.max_accelerated_files=4000 # 最大加速文件数(需覆盖项目所有PHP文件) opcache.revalidate_freq=60 # 文件修改检查频率(秒),生产环境可设为0(禁用检查)或更高(如3600) opcache.fast_shutdown=1 # 快速关闭,减少进程结束时的资源回收时间
phpinfo.php
页面,搜索“opcache”确认状态为“enabled”。3. 优化系统内核参数
调整Linux内核参数可提升PHP-FPM的网络和文件处理能力:
echo "fs.file-max = 100000" >> /etc/sysctl.conf # 系统全局最大文件描述符 echo "ulimit -n 65535" >> /etc/security/limits.conf # 单个进程最大文件描述符 sysctl -p # 生效配置
echo "net.core.somaxconn = 65535" >> /etc/sysctl.conf # 监听队列最大长度(需与Web服务器的`backlog`一致) echo "net.ipv4.tcp_max_syn_backlog = 65535" >> /etc/sysctl.conf # SYN队列最大长度 echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf # 复用TIME-WAIT状态的连接 echo "net.ipv4.tcp_fin_timeout = 30" >> /etc/sysctl.conf # TIME-WAIT状态超时时间(秒) sysctl -p # 生效配置 ```。
4. 调整请求处理超时参数
合理设置超时可避免长时间运行的脚本占用进程资源:
www.conf
)中设置:request_terminate_timeout = 30s # 脚本最大执行时间(秒),根据业务需求调整(如API接口可设为10s,复杂报表可设为60s)
fastcgi_read_timeout
(需大于PHP-FPM的request_terminate_timeout
):location ~ \.php$ { fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_read_timeout 60s; # Nginx等待PHP-FPM响应的超时时间 } ```。
5. 使用持久化连接减少数据库开销
数据库连接是PHP应用的常见瓶颈,使用持久化连接可避免频繁建立/断开连接的开销:
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password', [ PDO::ATTR_PERSISTENT => true // 开启持久化连接 ]);
max_connections
(如设为100-200),确保能承载持久化连接的峰值。6. 引入缓存层减少重复计算
使用缓存系统(如Redis、Memcached)存储频繁访问的数据(如数据库查询结果、会话信息),减少对数据库和PHP脚本的访问:
$redis = new Redis(); $redis->connect('127.0.0.1', 6379); $data = $redis->get('cache_key'); if (!$data) { $data = $db->query('SELECT * FROM large_table')->fetchAll(); // 数据库查询 $redis->setex('cache_key', 3600, serialize($data)); // 缓存1小时 } else { $data = unserialize($data); }
7. 监控与持续调优
通过监控工具识别性能瓶颈,针对性调整:
top
、htop
查看CPU、内存使用情况;vmstat 1
查看系统负载、进程状态;ss -lnt
查看TCP连接队列。pm.status_path = /status
,通过Nginx访问/status
页面查看进程数、请求处理时间等指标。slowlog = /var/log/php-fpm/slow.log request_slowlog_timeout = 2s # 记录执行时间超过2秒的请求 ```。
8. 其他优化措施
unset()
),避免内存泄漏。