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 # 緩存內存大?。∕B),根據腳本數量調整(如128MB可緩存約4000個文件)
opcache.interned_strings_buffer=8 # 內部字符串緩沖區大?。∕B)
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()
),避免內存泄漏。