[英]Why php curl uses forked apache processes and php_start_session()?
我正在使用一個php腳本,該腳本使用curl對數千個其他服務器執行http調用。 我注意到運行類似下面的php代碼時,apache進程的數量不斷增加:
$ch = curl_init($this->server);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Content-Length: ".strlen($data)));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$res = curl_exec($ch);
一段時間后,我使用gdb檢查了一些正在運行的apache進程,對於其中許多進程,我得到了如下回溯信息:
#0 0x00007fa1fec1d617 in flock () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007fa1fbbaf53b in ?? () from /usr/lib/apache2/modules/libphp5.so
#2 0x00007fa1fbbaf7a2 in ?? () from /usr/lib/apache2/modules/libphp5.so
#3 0x00007fa1fbbae524 in php_session_start () from /usr/lib/apache2/modules/libphp5.so
#4 0x00007fa1fbbaebb9 in ?? () from /usr/lib/apache2/modules/libphp5.so
#5 0x00007fa1fbd6fe8d in ?? () from /usr/lib/apache2/modules/libphp5.so
#6 0x00007fa1fbd209fb in execute () from /usr/lib/apache2/modules/libphp5.so
#7 0x00007fa1fbcfbf60 in zend_execute_scripts () from /usr/lib/apache2/modules/libphp5.so
#8 0x00007fa1fbca85d3 in php_execute_script () from /usr/lib/apache2/modules/libphp5.so
#9 0x00007fa1fbd8b46d in ?? () from /usr/lib/apache2/modules/libphp5.so
#10 0x00007fa1ffa12508 in ap_run_handler ()
#11 0x00007fa1ffa1297e in ap_invoke_handler ()
#12 0x00007fa1ffa21c1c in ap_internal_redirect ()
#13 0x00007fa1f9f74635 in ?? () from /usr/lib/apache2/modules/mod_rewrite.so
#14 0x00007fa1ffa12508 in ap_run_handler ()
#15 0x00007fa1ffa1297e in ap_invoke_handler ()
#16 0x00007fa1ffa225b0 in ap_process_request ()
#17 0x00007fa1ffa1f3d8 in ?? ()
#18 0x00007fa1ffa18fa8 in ap_run_process_connection ()
#19 0x00007fa1ffa27210 in ?? ()
#20 0x00007fa1ffa2797a in ?? ()
#21 0x00007fa1ffa28527 in ap_mpm_run ()
#22 0x00007fa1ff9fd4a4 in main ()
因此,使用curl可以啟動新的php會話。 由於我使用的是一些遺留的php代碼,它執行session_start()但不使用session_write_close(),因此我可以理解,這樣的過程不會結束。 因此我將session_write_close()放在curl_init()調用之前,然后apache進程的數量仍然很少。
所有curl調用都在工作,所有http調用都成功,數據到達等。
因此,我最后提出了幾個未解決的問題:
我認為您遇到的問題與curl的使用無關。
有關會話的默認PHP配置是基於文件的會話存儲機制。 文件訪問是排他的。 這樣的結果是每個會話一次只能由一個腳本使用。 如果第二個腳本使用相同的會話ID調用session_start()
,它將阻塞該調用,直到第一個腳本完成執行並關閉會話文件。 結果是(或可能是)您可能會看到等待過程的增加,特別是如果在所有請求被阻止的情況下一次又一次嘗試訪問該網站時。
該問題的解決方案是在不再需要會話處理程序時(使用session_write_close
)關閉會話處理程序,尤其是在耗時的任務(例如使用readfile()
發送文件或執行長時間運行的CURL請求)之前關閉會話處理程序。
因此,您的解決方案對我來說似乎不錯,只是解釋朝錯誤的方向進行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.