rhasm.net/blog

興味の赴くままに色々紹介し、解説をするブログです。

*

nginxとphp-fpmを調整する

      2015/08/30

Ngingとphp-fpmを調整する

しばらく放置しておいたら何とも言えないくらいにサーバが遅くなりました。
ページが開かない、エラーで落ちる、遅い。遅い。遅い。

というわけで、調整をします。

エラーを調べる

まずは、エラーログをチェックしていきます。
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 – you may need to increase pm.start_servers, or pm.min/max_spare_servers – Warningエラー対処法 | Linux入門

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のservers設定を変更して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

そして観察へ・・・

というわけで、それから数日経過しています。今のところ重い現象は起こっていません。まだしばらく様子見をしますが、たぶんこれで大丈夫なのかなーと思っています。

ではでは。

 - コンピュータ, サーバサイド ,