天天看點

php-fpm 逾時,小心 php fpm 的逾時

一次線上問題,讓我意識到,fpm 居然是用這種方式處理逾時的,雖然有點震驚,但是想想,這才是我大 PHP 處理問題的方式,簡單粗暴而且高效。

問題的現象是這樣的,某個接口通路量大增,然後接口大量502,接着 fpm 的機器cpu暴漲,最後gg。

fpm 處理逾時的方式非常簡單,那就是,直接退出 worker 子程序。

對于逾時的處理,fpm 的代碼裡是這樣寫的的(我隐去了細節,有興趣的可以去 PHP 官網下載下傳一份源碼看看,在源碼的 sapi/fpm 目錄裡) 檢測逾時

static void fpm_pctl_check_request_timeout(struct timeval *now)

{

……

fpm_request_check_timed_out(child, now, terminate_timeout, slowlog_timeout);

……

}

處理逾時

void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now, int terminate_timeout, int slowlog_timeout)

{

……

fpm_pctl_kill(child->pid, FPM_PCTL_TERM);

……

}

}

然後kill

int fpm_pctl_kill(pid_t pid, int how)

{

……

return kill(pid, s);

}

然後問題就清楚了,接口裡有個服務逾時,造成fpm逾時,fpm worker 程序不斷被kill掉并拉起新的 fpm worker 程序,然後不斷的這樣 kill 然後拉起,cpu 就暴漲,最後 gg。

這個問題怎麼避免,去掉 fpm 逾時是萬萬不可取的,隻能嚴格控制代碼,調用每一個外部服務必須設定逾時時間,而且這個逾時時間必須小于 fpm 逾時時間。

更多架構、PHP、GO相關踩坑實踐技巧請關注我的公衆号:PHP架構師