長時間運行的 cURL 多線程採集 HTTPS 頁面 (經 Privoxy 代理) 出現嚴重內存洩漏,memory_get_usage() 無感知,僅 top 觀察到 RSS 持續增長。經排查,需同時設置三個 SSL/代理相關選項徹底解決。
https://www.google.com/search?q=xxx 經 HTTP 代理。memory_get_usage() 正常,進程 RSS 線性增長。curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true); // 關鍵:建立 TCP 隧道
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳過證書驗證
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 不檢查證書 CN
無隧道模式 (默認):
隧道模式:
CONNECT host:443 給代理200 Connection establishedCURLOPT_SSL_VERIFYPEER=false:不驗證證書鏈信任鏈,避免 CA 束加載/驗證邏輯的內存殘留。CURLOPT_SSL_VERIFYHOST=0 (或 false):不檢查證書 Common Name,進一步減少 SSL 上下文分配。// 壓測腳本
for ($i=0; $i<10000; $i++) {
curl_exec($ch);
if ($i % 100 === 0) {
echo "RSS: " . (memory_get_usage(true)/1024/1024) . " MB\n";
// 同時 top -p PID 觀察 RES
}
}
修復前:RSS 每 1000 請求增長 ~50MB
修復後:RSS 穩定在基線 ±2MB
CURLOPT_CAINFO 指定 CA 憑證包,而非關閉驗證。curl_reset($ch) 重置選項,避免重複 curl_init/close 開銷。process_resident_memory_bytes 設置告警閾值。內存洩漏多發於 C 擴展與外部庫交互邊界,CURLOPT_HTTPPROXYTUNNEL 是 HTTPS 代理場景的「銀彈」,務必默認開啟。