nginxとphp-fpmを調整する
2015/08/30
しばらく放置しておいたら何とも言えないくらいにサーバが遅くなりました。
ページが開かない、エラーで落ちる、遅い。遅い。遅い。
というわけで、調整をします。
エラーを調べる
まずは、エラーログをチェックしていきます。
php-fpmのエラーログから。
emacs /var/log/php-fpm/error.log
で、胡散臭そうな警告が何度も出ているのを発見。
WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 4 idle, and 27 total children
プールしてあるコネクションを使い切ってるくさいよ。的な感じですかね。
どうも、nginxやらphp-fpmは最近のデータベース接続のように、ある程度接続をプールしておいて、そいつらを使いまわす方法をとっているようです。使い切ってる間にサーバにアクセスがあると、そのアクセスはプールに空きができるまで待たされる様子。
次に、nginxのエラーログをチェック。
emacs /var/log/nginx/error.log
こちらもわんさかエラーが出ていました。
[error] 28225#0: *4820 connect() to unix:/var/run/php-fpm/php-fpm.sock failed (11: Resource temporarily unavailable)
これはphp-fpmに待たされた果ての挙動なのかと解釈してみます。
php-fpmの設定を変更する
というわけで、これらのメッセージで調べてみたところ、いくつかのサイトで対処法が見つかりました。
PHP-FPM Problem | XenForo Community
php fpm – Nginx and PHP-FPM running out of connections – Server Fault
これらのサイトを見渡して総まとめすると、php-fpmの子プロセスのプール数を増やせという論調。
というわけで増やします。
emacs /etc/php-fpm.d/www.conf
エディタで数値を書き換えていきます。
; The number of child processes to be created when pm is set to 'static' and the ; maximum number of child processes to be created when pm is set to 'dynamic'. ; This value sets the limit on the number of simultaneous requests that will be ; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. ; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP ; CGI. ; Note: Used when pm is set to either 'static' or 'dynamic' ; Note: This value is mandatory. pm.max_children = 100 ; The number of child processes created on startup. ; Note: Used only when pm is set to 'dynamic' ; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 pm.start_servers = 10 ; The desired minimum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' pm.min_spare_servers = 10 ; The desired maximum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' pm.max_spare_servers = 50
そして、リスタート。
/etc/init.d/php-fpm restart
そして軽くなった
というわけで、ブログにアクセスをしてみると、軽い軽い。
よかったよかった。
解決です。さっそく記事を更新します。
と思ったけど、そうでもなかった
記事を更新しているうちに、どんどん重くなっていきます。
なおってない。更新は中止です。
サーバの状態をチェックする
何どうなってるのさ。
というわけで、サーバのプロセスの状態を知ろうと思い、コマンドは何だったっけと調べていたら、よい記事を見つけました。
top の代わりに htop を使ってみた。 | Lonely Mobiler
さっそく、記事の教えの通りにやってみることにします。
yum install htop htop
おー。わかりやすい。
わかりやすく、ものすごいメモリを使いつくしています。
あははは、これは無理だ。
というわけで、再度php-fpm設定
emacs /etc/php-fpm.d/www.conf
今回はこんな設定に。
; The address on which to accept FastCGI requests. ; Valid syntaxes are: ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on ; a specific port; ; 'port' - to listen on a TCP socket to all addresses on a ; specific port; ; '/path/to/unix/socket' - to listen on a unix socket. ; Note: This value is mandatory. ;listen = 127.0.0.1:9000 listen = /var/run/php-fpm/php-fpm.sock ; Set listen(2) backlog. A value of '-1' means unlimited. ; Default Value: -1 listen.backlog = 256 ;;; 中略 ;;; ; The number of child processes to be created when pm is set to 'static' and the ; maximum number of child processes to be created when pm is set to 'dynamic'. ; This value sets the limit on the number of simultaneous requests that will be ; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. ; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP ; CGI. ; Note: Used when pm is set to either 'static' or 'dynamic' ; Note: This value is mandatory. pm.max_children = 100 ; The number of child processes created on startup. ; Note: Used only when pm is set to 'dynamic' ; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 pm.start_servers = 1 ; The desired minimum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' pm.min_spare_servers = 1 ; The desired maximum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' pm.max_spare_servers = 2
まず、listen.backlogはコメントアウトされていましたが、実は-1が効いてないバグがあるよってことで、とりあえず256にしてみます。ここは5000だとか65536だとかいろいろ書いてありましたが、まあとりあえずです。調子悪かったらまた考える。
そして、servers関連は最小値にします。
子プロセスをぽこぽこ作るばかりが人生ではない!
nginxの設定を変更する
さらに、nginxの設定をします。
emacs /etc/nginx/conf.d/default.conf
こちらには、タイムアウトを設定。
# # The default server # server { listen 80; server_name ~^(.*\.)?rhasm.net; access_log /xxxxxx/access.log; error_log /xxxxxx/error.log; #charset koi8-r; #access_log logs/host.access.log main; location / { root /var/www/$host; index index.php; if (!-e $request_filename) { rewrite ^.+?($/-.*) $1 last; rewrite ^.+?(/.*\.php)$ $1 last; rewrite ^ /index.php last; } proxy_read_timeout 300; }
以上の設定をした後、再起動。
/etc/init.d/php-fpm restart /etc/init.d/nginx restart
そして観察へ・・・
というわけで、それから数日経過しています。今のところ重い現象は起こっていません。まだしばらく様子見をしますが、たぶんこれで大丈夫なのかなーと思っています。
ではでは。