堅(jiān)持為客戶提供有價(jià)值的服務(wù)和內(nèi)容

[北京網(wǎng)站制作]PHP-CGI 進(jìn)程 CPU 100% 與 file_get_contents 函數(shù)的關(guān)系

商企云 | 2021-06-18 | 分享至:

PHP-CGI 進(jìn)程 CPU 100% 與 file_get_contents 函數(shù)的關(guān)系

有時(shí)候,運(yùn)行 Nginx、PHP-CGI(php-fpm) Web服務(wù)的 Linux 服務(wù)器,突然系統(tǒng)負(fù)載上升,使用 top 命令查看,很多 php-cgi 進(jìn)程 CPU 使用率接近100%。后來,我通過跟蹤發(fā)現(xiàn),這類情況的出現(xiàn),跟 PHP 的 file_get_contents() 函數(shù)有著密切的關(guān)系。(北京網(wǎng)站建設(shè))

  大、中型網(wǎng)站中,基于 HTTP 協(xié)議的 API 接口調(diào)用,是家常便飯。PHP 程序員們喜歡使用簡單便捷的 file_get_contents("http://example.com/") 函數(shù),來獲取一個(gè) URL 的返回內(nèi)容,但是,如果 http://example.com/ 這個(gè)網(wǎng)站響應(yīng)緩慢,file_get_contents() 就會(huì)一直卡在那兒,不會(huì)超時(shí)。

  我們知道,在 php.ini 中,有一個(gè)參數(shù) max_execution_time 可以設(shè)置 PHP 腳本的最大執(zhí)行時(shí)間,但是,在 php-cgi(php-fpm) 中,該參數(shù)不會(huì)起效。真正能夠控制 PHP 腳本最大執(zhí)行時(shí)間的是 php-fpm.conf 配置文件中的以下參數(shù):

  1. The?timeout?(in?seconds)?for?serving?a?single?request?after?which?the?worker?process?will?be?terminated????
  2. Should?be?used?when?'max_execution_time'?ini?option?does?not?stop?script?execution?for?some?reason????
  3. '0s'?means?'off'????
  4. 0s???

  默認(rèn)值為 0 秒,也就是說,PHP 腳本會(huì)一直執(zhí)行下去。這樣,當(dāng)所有的 php-cgi 進(jìn)程都卡在 file_get_contents() 函數(shù)時(shí),這臺(tái) Nginx+PHP 的 WebServer 已經(jīng)無法再處理新的 PHP 請(qǐng)求了,Nginx 將給用戶返回“502 Bad Gateway”。修改該參數(shù),設(shè)置一個(gè) PHP 腳本最大執(zhí)行時(shí)間是必要的,但是,治標(biāo)不治本。例如改成 30s,如果發(fā)生 file_get_contents() 獲取網(wǎng)頁內(nèi)容較慢的情況,這就意味著 150 個(gè) php-cgi 進(jìn)程,每秒鐘只能處理 5 個(gè)請(qǐng)求,WebServer 同樣很難避免“502 Bad Gateway”。

  要做到徹底解決,只能讓 PHP 程序員們改掉直接使用 file_get_contents("http://example.com/") 的習(xí)慣,而是稍微修改一下,加個(gè)超時(shí)時(shí)間,用以下方式來實(shí)現(xiàn) HTTP GET 請(qǐng)求。要是覺得麻煩,可以自行將以下代碼封裝成一個(gè)函數(shù)。

  1. $ctx?=?stream_context_create(array(????
  2. ???'http'?=>?array(????
  3. ???????'timeout'?=>?1?//設(shè)置一個(gè)超時(shí)時(shí)間,單位為秒????
  4. ???????)????
  5. ???)????
  6. );????
  7. file_get_contents("http://example.com/",?0,?$ctx);????
  8. ?>???

  當(dāng)然,導(dǎo)致 php-cgi 進(jìn)程 CPU 100% 的原因不只有這一種,那么,怎么確定是 file_get_contents() 函數(shù)導(dǎo)致的呢?

  首先,使用 top 命令查看 CPU 使用率較高的 php-cgi 進(jìn)程。

  1. top?-?10:34:18?up?724?days,?21:01,??3?users,??load?average:?17.86,?11.16,?7.69?
  2. Tasks:?561?total,??15?running,?546?sleeping,???0?stopped,???0?zombie?
  3. Cpu(s):??5.9%us,??4.2%sy,??0.0%ni,?89.4%id,??0.2%wa,??0.0%hi,??0.2%si,??0.0%st?
  4. Mem:???8100996k?total,??4320108k?used,??3780888k?free,???772572k?buffers?
  5. Swap:??8193108k?total,????50776k?used,??8142332k?free,???412088k?cached?
  6. ??PID?USER??????PR??NI??VIRT??RES??SHR?S?%CPU?%MEM????TIME+??COMMAND????????????????????????????????????????????????????????????
  7. 10747?www???????18???0??360m??22m??12m?R?100.6?0.3????0:02.60?php-cgi????????????????????????????????????????????????????????????
  8. 10709?www???????16???0??359m??28m??17m?R?96.8??0.4????0:11.34?php-cgi????????????????????????????????????????????????????????????
  9. 10745?www???????18???0??360m??24m??14m?R?94.8??0.3????0:39.51?php-cgi????????????????????????????????????????????????????????????
  10. 10707?www???????18???0??360m??25m??14m?S?77.4??0.3????0:33.48?php-cgi????????????????????????????????????????????????????????????
  11. 10782?www???????20???0??360m??26m??15m?R?75.5??0.3????0:10.93?php-cgi????????????????????????????????????????????????????????????
  12. 10708?www???????25???0??360m??22m??12m?R?69.7??0.3????0:45.16?php-cgi????????????????????????????????????????????????????????????
  13. 10683?www???????25???0??362m??28m??15m?R?54.2??0.4????0:32.65?php-cgi????????????????????????????????????????????????????????????
  14. 10711?www???????25???0??360m??25m??15m?R?52.2??0.3????0:44.25?php-cgi????????????????????????????????????????????????????????????
  15. 10688?www???????25???0??359m??25m??15m?R?38.7??0.3????0:10.44?php-cgi????????????????????????????????????????????????????????????
  16. 10719?www???????25???0??360m??26m??16m?R??7.7??0.3????0:40.59?php-cgi?

  找其中一個(gè) CPU 100% 的 php-cgi 進(jìn)程的 PID,用以下命令跟蹤一下:

  1. strace?-p?10747?

  如果屏幕顯示:

  1. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  2. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  3. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  4. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  5. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  6. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  7. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  8. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  9. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  10. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  11. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  12. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  13. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  14. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  15. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  16. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  17. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  18. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?
  19. select(7,?[6],?[6],?[],?{15,?0})????????=?1?(out?[6],?left?{15,?0})?
  20. poll([{fd=6,?events=POLLIN}],?1,?0)?????=?0?(Timeout)?

  那么,就可以確定是 file_get_contents() 導(dǎo)致的問題了。

掃二維碼與項(xiàng)目經(jīng)理溝通

7*24小時(shí)為您服務(wù)

解答:網(wǎng)站優(yōu)化,網(wǎng)站建設(shè),APP開發(fā),小程序開發(fā),H5開發(fā),品牌推廣,新聞推廣,輿情監(jiān)測等

  非常感謝您有耐心的讀完這篇文章:"[北京網(wǎng)站制作]PHP-CGI 進(jìn)程 CPU 100% 與 file_get_contents 函數(shù)的關(guān)系",更多內(nèi)容請(qǐng)繼續(xù)瀏覽,我們將為您提供更多參考使用或?qū)W習(xí)交流的信息。我們還可為您提供:網(wǎng)站建設(shè)與開發(fā)、網(wǎng)站優(yōu)化品牌推廣、APP開發(fā)、小程序開發(fā)、新聞推廣等服務(wù),我們以“降低營銷成本,提高營銷效果”的服務(wù)理念,自創(chuàng)立至今,已成功服務(wù)過不同行業(yè)的1000多家企業(yè),獲得國家高新技術(shù)企業(yè)認(rèn)證,且擁有14項(xiàng)國家軟件著作權(quán),將力爭成為國內(nèi)企業(yè)心目中值得信賴的互聯(lián)網(wǎng)產(chǎn)品及服務(wù)提供商。如您需要合作,請(qǐng)掃碼咨詢,我們將誠摯為您服務(wù)。
我要咨詢
姓名 :
電話 :
文章分類