Apacheチューニング方法（Apache2.4, prefork）

# はじめに
ApacheによるWebサーバーを公開する際に、公開範囲や規模によってApacheの設定もチューニングする必要があります。今回は、preforkでのチューニング方法の一例を紹介します。


# preforkとは？？
- Apacheのプロセスの挙動の方式の一つ
- スレッドを使わずに、fork（自分自身のコピー）を行う＝prefork
- あらかじめ（pre）Apacheの子プロセスをコピー（fork）しておき、forkの待ち時間を減らすことでパフォーマンスを上げている
- forkされた子プロセス一つ一つが通信を受け持つ
- 他の子プロセスがおかしな挙動をしても、他の子プロセスには影響がないため、安定した通信が可能
- preforkで多数のクライアントを裁くには、多数のメモリ・CPUを使用する


# 前提
- CentOS7.2
- Apache2.4
- サイジング済み（想定されるリクエスト数、使用メモリ、CPUは計算済み）


# 設定方法
**今回は設定を分かりやすくするために、mpm.confというファイルに記載します。**
→httpd.confに記載してもOKです。

1.プロセスの挙動方式の確認
> preforkと似ているものに、workerというものがあります。
> デフォルトではpreforkですが、念のため確認しましょう。

```
# apachectl -V
Server version: Apache/2.4.25 (CentOS)
Server built:   Jan  6 2017 14:54:10
Server's Module Magic Number: 20120211:67
Server loaded:  APR 1.5.2, APR-UTIL 1.5.4
Compiled using: APR 1.5.2, APR-UTIL 1.5.4
Architecture:   64-bit
Server MPM:     prefork ←★ここを確認！
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/run/httpd/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"
```

```Server MPM:     prefork```となっていればOKです！


2.設定前の確認
> 今回はアパッチのプロセス数を増やすので、増やす前の状態を確認しましょう。

```
# ps -ef | grep httpd
root       941     1  0 Mar21 ?        00:00:16 /usr/sbin/httpd -DFOREGROUND
apache    2149   941  0 Mar21 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2150   941  0 Mar21 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2151   941  0 Mar21 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2152   941  0 Mar21 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    2153   941  0 Mar21 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
root      8109  8035  0 14:35 pts/0    00:00:00 grep httpd
```

この数を覚えときましょう！
**基本設定するときは、作業前の確認をしましょう！**
→これをしないと、設定後にどう変化したのか分からなくなってしまいます。。。

3.mpm.confの作成
> アパッチのチューニング内容を記載するファイルを作成します。
> ```vi```コマンドで作成、記述を一気に行ってもOKです。

```
# touch /etc/httpd/conf.d/mpm.conf
```

4.mpm.confに記載
> 実際のチューニング内容を記載します。
> **※記載内容は、サイジングによって異なります！**

```
<IfModule mpm_prefork_module>
    StartServers 400　←起動時に生成される子サーバプロセスの数。デフォルトは5。
    MinSpareServers 400　←アイドル状態にいる子サーバプロセスの最小（希望）個数。デフォルトは5。
    MaxSpareServers 400　←アイドル状態にいる子サーバプロセスの最大（希望）個数。デフォルトは10。
    ServerLimit 400　←MaxClientsに指定可能な値の上限。（MaxClientより大きな数にする）
    MaxClients 400　←応答できる同時リクエスト数。デフォルトは256。
    MaxRequestsPerChild 80　←個々の子サーバプロセスが扱うことのできるリクエストの総数。デフォルトは10000。0にすると無制限
</IfModule>
```

5.httpd.confに追記
> 今回は併せて下記も追記しました。

```
KeepAlive On　←クライアントからの接続要求時に即座にセッションを閉じないようにする設定
MaxKeepAliveRequests 80　←一度に処理できる数の最大値（1ページあたりの平均ファイル数+αが参考値）
KeepAliveTimeout 120　←KeepAlive有効時に接続要求を受け付ける数の最大許容値（1ページ当たりの平均的な転送時間+αが参考値）
```

6.設定の反映
> 上記で行なった設定を反映させるために、Apacheの再起動を行います。

```
# systemctl restart httpd
```

7.設定後のプロセス確認
> 手順2.と比較しましょう！

```
# ps -ef | grep httpd
root      8120     1 87 14:36 ?        00:00:05 /usr/sbin/httpd -DFOREGROUND
apache    8121  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8123  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8124  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8126  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8129  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8131  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8133  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8134  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8136  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8137  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8139  8120  1 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8140  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8141  8120  1 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8142  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8143  8120  2 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8144  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8145  8120  2 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8146  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8147  8120  1 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8148  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8149  8120  1 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8163  8120  1 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8165  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8167  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8169  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8171  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8173  8120  0 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8175  8120  1 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8177  8120  5 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8179  8120  2 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8181  8120  4 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8183  8120  2 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache    8185  8120  8 14:36 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
root      8188  8035  0 14:36 pts/0    00:00:00 grep httpd
```

すごい増えました！
メモリ、CPUのサイジングに失敗するとサーバーがダウンするのできちんとサイジングしましょう。
確かこの設定を行ったときは、メモリ32GBのサーバーを5台は入れていたような。。。。（あまり覚えていません。。。）

完了！



# 余談
### なぜmpm.confという名前にしたのか
- mpm_prefork_moduleを使っているから
- MPM＝マルチプロセッシングモジュール
- マルチプロセスとは、リクエストごとにforkを行い、子プロセスを生成し、処理をしてもらう
- MPMとは、リクエストを処理する部分のことを指す
- prefork, worker, eventなどがある

### workerとは
- 子プロセスがマルチスレッドで操作し、スレッドがクライアントを受け持つ
- 1つのプロセスが複数の通信を行う（プロセスの中に、通信をするスレッドが複数いる）
- プロセスの起動を抑えることが可能なため、CPUやメモリの使用率を抑えることが可能

### eventとは
- workerと同じで、マルチスレッドで動作する
- 違いは、Keep-Alive（持続的接続）の処理方法
- preforkやworkerは同じプロセスやスレッドを持続接続の際に利用するが、workerでは別のスレッドに割り振る


## MPMの切り替え方法(Apache2.4)
デフォルトのpreforkからworkerに変更します

1.変更前の確認

```
# apachectl -V | grep MPM
Server MPM:     prefork
```

2.MPMの切り替え

```
# /etc/httpd/conf.modules.d/00-mpm.conf
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so　←★コメントアウトします！

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
LoadModule mpm_worker_module modules/mod_mpm_worker.so　←★コメントアウトを外します！

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so
```

3.設定の反映

```
# systemctl restart httpd
```

4.設定後の確認

```
# apachectl -V | grep MPM
Server MPM:     worker
```