php-fpm ってなんだっけ？（個人備忘録）

###初めに
dockerにてnginx,php-fpmにて環境構築を行った際に、これらをあまり理解しないまま、使用し動いていたからOKとなっていた状況でありました。その為個人の復習の為、記述しました。
概要を理解し、しっかり設定ファイルを作ることで例外が起きた時に適切なデバックができると考えました。
###その前にCGIについて
>Webサーバ上でユーザプログラムを動作させるための仕組み。 Webサーバプログラムの機能の主体は、あらかじめ用意された情報を利用者（クライアント）の要求に応じて送り返すことである。そのためサーバプログラム単体では情報をその場で動的に生成してクライアントに送信するような仕組みを作ることはできなかった。　
そこでサーバプログラムから他のプログラムを呼び出し、その処理結果をクライアントに送信する方法が考案され、それを実現するためのサーバプログラムと外部プログラムとの連携法の取り決めがCGIである。　
Webサーバ上でPHP（動的コンテンツを生成する言語）を動作させるための仕組み。

###続いてfastCGIとは
>Webサーバ上でユーザプログラムを動作させるためのインターフェース仕様の一つ。
CGIは、ユーザから要求がある度に、プロセスの生成と破棄を行う。大量の要求があればその分だけプロセスの生成と破棄が実施され、この事がパフォーマンスの悪化に繋がっていく。
FastCGIは、初回リクエスト時に起動したプロセスをメモリ上へ保持を行い、次回リクエストに対してはそのメモリに保持したプロセスの実行を行うことで、CGI問題を解決し、プログラム動作速度の向上及びサーバ負荷の低下が可能である。

予め想定プロセスのキャッシュを行っておくことで、リクエストに対応する仕組み。
cgiだとリクエストの旅にプロセスの生成と破棄を繰り返す為、リクエストが増える度にサーバー負荷↑、それを予め予想されるプロセスを前もって生成し対応しましょうねという機能

###php-fpmとは
>FPM（FastCGI Process Manager)はPHPのFastCGI実装のひとつ
主に高負荷のサイトで有用な追加機能を用意している。
webサーバー上でPHPを実行する仕組みがphp-fpm

php版のfast CGIということ。webサーバー上でphpのプロセスのキャッシュをメモリ保持して、それを有効活用するもの。こうしておくことで、予めリ予想されるクエストに対して処理の対応を確立して、対応しましょうねということ。

今回の構成ではnginxはリバースプロキシーとして動作、cgiのパラムスをphp-fpmでunixドメインソケット通信で送って、処理をしている。

```
<nginx>
server {
    listen 80;
    中略
    location ~ \.php$ {
        fastcgi_pass  unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        include       fastcgi_params;
    }
}

<php-fpm>
www.conf
[www]
user = www-data
group = www-data
listen = /var/run/php-fpm.sock
listen.owner = root
listen.group = root
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
```

php-fpmの設定ファイルにてリクエストに対してどういう対処をするのかを設定していますね！

------------------
###php-fpmの設定ファイルについて
php-fpmの設定ファイルはphp-fpm.conf
プール設定はwww.conf

####グローバル設定項目
phpーfpm自体のエラーログを出力する様にします。
[global]
pid = /var/run/php-fpm.pid
error_log = /var/log/php-fpm.log
####プール項目
>プールとは
リクエストに対応すべき、ワーカープロセスから予め用意（設定）生成された、プロセスの集まりのこと。サーバーに届いたリクエストの処理に割り当てます。

このプール設定のことをプール項目といいます。

**listen**
リクエストを待ち受けるポート or UNIX ドメインソケットを指定します。

**user / group**
プロセスの実行ユーザー/グループを指定する。

**listen.mode**
UNIX ドメインソケットを利用する場合の、ソケットのパーミッションを指定します。chmodコマンドと同じ方法で指定します。

**listen.owner / listen.group**
UNIX ドメインソケットを利用する場合の、ソケットのオーナー/グループを指定します。Webサーバーからリクエストを受け付けるには、Webサーバーがソケットに対して読み書き可能でなければいけません。

####プロセス数の制御
**static**
 設定した数を常に起動しておく方法。プロセスの起動に伴うオーバーヘッドがないという利点があります。ただし、最大同時接続可能数を上げようとすればするほど常に多くメモリを必要とするようになるという短所もあります。
メモリに対してCPUの処理能力が低いサーバに向いてい

ます。
**dynamic**
起動数を動的に変更する方法。
通常時はある程度の数プロセスを起動しておきます。同時接続数が増え、プロセス数が足りなくなった時だけ、設定した範囲でプロセスが追加で起動されます


dynamic のほうが柔軟に処理能力を調整することができるので、より良いようにも思えます。しかし、**プロセスはリクエストの処理中CPU1コアを占有**するので、同時処理可能なリクエスト数はCPUの論理コア数に依存します。
したがって、一般的なサーバーの場合メモリやディスクの限界に達する前にCPUがボトルネックとなるので、あまり多くの数プロセスを起動しても意味がありません。

それならば、プロセスの動的な起動に伴うオーバーヘッドがないstaticを選択するほうが良い場合も多いそうです。

**pm.max_children**
プロセスの最大起動数を表します。サーバーの同時接続可能数を決定します。
プロセス数制御がstaticの場合、常にここで指定された数のプロセスを起動します。この数値を超える同時接続があった場合、超えた分のリクエストは、他のリクエストの処理後に処理されるので、レスポンスタイムが悪化します。

ではこの設定を多くとっておいたらいいじゃんとなりますが、CPUのコア数を超えた設定をしても同時に実行できませんし、メモリ消費量が多ければ、swap領域を使用してします。なので使用するリソースに応じた値を設定することが必要です。

pm.max_children = Webサーバー専用の合計RAM /最大子プロセスサイズ

**pm.max_requests**
プロセスを再起動する処理リクエスト数を指します。
プロセスの肥大化で触れた通り、多くのリクエストを処理すると、プロセスで使用するメモリがどんどん増大していくことがあります。
これを防ぐために、一定数リクエストを処理したプロセスを自動で再起動させることができます。この設定では、そのリクエスト数を指定します

ー　各プロセスが1日に処理するリクエスト数は、1日のリクエスト（PV）数 ÷ pm.max_children
　　この割り出した値を設定する。

**pm.max_spare_servers**
アイドル状態のプロセス最大起動数を指します。リクエストの処理を待機しているプロセスを、最大でいくつ起動しておくかという設定です。
この設定は、通常時に（アクセスのピーク時間帯以外に）常時起動するプロセスの最大数とも捉えることができます。したがって、通常時サーバーで動いている他のプロセスのリソースを奪わない程度の値を設定します。

**pm.min_spare_servers**
アイドル状態のプロセス最小起動数を指します。リクエストの処理を待機しているプロセスを、最低限いくつ起動しておくかという設定です。この設定項目は、「新たなプロセスを起動せずにリクエストを処理する余裕」を最低限どの程度持っておくかということを決定します。

**pm.start_servers**
親プロセスの開始時に起動する子プロセスの数です。この数値を基準にして、pm.max_spare_serversとpm.min_spare_serversをもとにプロセス数が決定されます。

-----------------
**今回の設定**

```
<php-fpm.conf>
[global]
pid = /var/run/php-fpm.pid
error_log = /var/log/php-fpm.log
include=/usr/local/etc/php-fpm.d/*.conf

<www.conf>
[www]
user = www-data
group = www-data
listen = /var/run/php-fpm.sock
listen.owner = root
listen.group = root
pm = dynamic
pm.max_children = 20
pm.start_servers = 20
pm.min_spare_servers = 20
pm.max_spare_servers = 20
```
php-fpm.comfで全体の設定を行います。logの出力をしておいて、プール設定はファイルを切り分けしています。
includeでwww.confを読み込んでいます。

www.conf はチューニングの設定を行っています。
またuser、groupはwww-dataに設定しています。phpの実行ユーザーを指定しています。
webサーバのデフォルトの実行ユーザはディストリビューションによって変わるらしいです。

listen.owner, listen.group 
> phpドキュメント　
unix ソケットを使う場合に、そのパーミッションを設定します。デフォルト値: ユーザーとグループは実行しているユーザーと同じ、モードは 0660


今回はコンテナの中なので、rootを指定。
pmはダイナミックで、以下パラメータはデプロイ時に設定を変えて現在のものとなっています。
のち再度チューニングをして行こうと思いますが、CPUのパフォーマンスにあったのもを選択しようと思います。

###まとめ
振り返り、CUPにあった適切なチューニングを行うことでサイトパフォーマンスを向上させることを学びました。理解を深めてチューニングをいきたいです。