メモリとCPUに余裕があるのにnginxで503エラーが出て、php-fpmが止まった

特に前兆はなく(実はあったんだけど)サーバーが死んだ。

最近はアクティブユーザーが増えてくれて、POSTで1日200万リクエスト(転送量20GB)をこえたりしてたんだけど、突然503エラーで完全に応答しなくなった。(アプリでは通信エラーと出る)

構成としてConohaの メモリ 4GB/CPU 4Core×2台

これをロードバランサーでつないでいる。

 

まぁhtopでロードアベレージも両サーバー0.6とかで、これだったら余裕だろ~って眺めてたら死んだ。

てか実際に落ちたときにhtopで確認したけどロードアベレージが1を超えてなかった。

なんで??という思いが強かったけど、TCPコネクション使い切ったとおもって、とりあえずサーバーリブートで問題なく治った。

これはメモリリークの可能性があるなと思って(サーバー自体は半年以上再起動とかしてない)

とりあえず、様子見したら一日問題なく動いた。

 

実は設定悪い可能性があります!

 

nginx_error.log

connect() to unix:/var/run/php-fpm/php-fpm.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client:

 

php-fpm-error.log

[21-Jan-2021 10:50:43] WARNING: [pool www] server reached pm.max_children setting (100), consider raising it
[21-Jan-2021 11:01:23] NOTICE: Terminating …
[21-Jan-2021 11:01:23] NOTICE: exiting, bye-bye!
[21-Jan-2021 11:01:43] NOTICE: fpm is running, pid 1009
[21-Jan-2021 11:01:43] NOTICE: ready to handle connections
[21-Jan-2021 11:01:43] NOTICE: systemd monitor interval set to 10000ms
[21-Jan-2021 11:01:52] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 0 idle, and 17 total children
[21-Jan-2021 11:01:53] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 0 idle, and 25 total children
[21-Jan-2021 11:01:54] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 35 total children
[21-Jan-2021 11:01:55] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 45 total children
[21-Jan-2021 11:01:56] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 55 total children
[21-Jan-2021 11:01:57] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 65 total children
[21-Jan-2021 11:01:58] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 9 idle, and 75 total children
[21-Jan-2021 11:01:59] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 9 idle, and 76 total children
[21-Jan-2021 11:02:21] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 8 idle, and 84 total children
[21-Jan-2021 11:02:22] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 9 idle, and 86 total children
[21-Jan-2021 11:02:45] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 8 idle, and 98 total children
[21-Jan-2021 11:02:49] WARNING: [pool www] server reached pm.max_children setting (100), consider raising it

 

まずworker_processes を確認!

worker_processes auto;←これが良い

これがworker_processes  1(!?)になってた

CPUコア4なのに、これじゃあ1個しか使わない

あとコネクションの上限も念の為あげとく
worker_rlimit_nofile 16384;

events {
worker_connections 4096;
}

※worker_rlimit_nofileは設定しないと1024とかに制限されちゃうから必要

 

前提としてdynamicで

あと、php-fpmが平均してどれぐらいメモリ使うかによってpm.max_children

の設定も変えましょう

pm.max_children = 200

にした

ps -ylC php-fpm –sort:rss

で調べれる

RSSがメモリ使用率でKBで表示されます(24116だったら24116KB)

だいたい雰囲気の平均をとって、20MBぐらいだな~とおもって

メモリ4GBだったら

4000MB/20MBの200

この200をpm.max_childrenにした(本当はもっと安全をとって低いほうがいいかも)

参考→https://myshell.co.uk/blog/2012/07/adjusting-child-processes-for-php-fpm-nginx/

 

あとpm.max_requestsが自分的にはちょっと大事!

今まではpm.max_requestsはデフォルトの0にしていた

でも多分メモリリークの可能性があって、メモリ使い切って不安定になった可能性がある。このpm.max_requestsっていうのはmax_requestsの回数に達したらプロセスを再起動する設定になるからメモリリークがあっても解消できる。

つまりこれが実は大事だったかも。

ただ現在、1日200万PVなので1日ぐらいで再起動させたい場合、

1日のリクエスト(PV)数 ÷ pm.max_spare_serversになるので

だいたい50000ぐらい?

なんか凄く大きな値になった。

まぁ0よりはいいでしょう

 

とりあえずこれで様子をみる。

 

追記:念のためメモリも8GBにした。

でもこれ多分2台でやる、 8GB×8GBより4GB×4GB×4GBとかのほうが良い気もする。