rhasm.net/blog

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

*

nginxとphp-fpmを調整する

      2015/08/30

Ngingとphp-fpmを調整する

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

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

エラーを調べる

まずは、エラーログをチェックしていきます。
php-fpmのエラーログから。

emacs /var/log/php-fpm/error.log

で、胡散臭そうな警告が何度も出ているのを発見。

1
2
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

こちらもわんさかエラーが出ていました。

1
[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

エディタで数値を書き換えていきます。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
; 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

今回はこんな設定に。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
; 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

こちらには、タイムアウトを設定。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#
# 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

そして観察へ・・・

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

ではでは。

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

S