0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastAPIの非同期ブロッキングを、Apache・Nginxの並行処理モデル(プロセス/スレッド)から理解する

0
Last updated at Posted at 2026-02-21

はじめに

FastAPIでOpenAI APIやClaude APIのような、レスポンス待ち(I/O待ち)が長い処理を実装した際、「非同期にしているはずなのに、なぜかリクエストが詰まってしまう」という現象に直面しました。

調査を進めていく中で、プロセス・スレッド・イベントループという概念を理解する必要があることが分かりました。

その際に、Apacheのプロセス・スレッドのアーキテクチャの限界(C10K問題)をNginxが解決したという話を思い出したため、
ApacheからNginxへのアーキテクチャの変遷を紐解いた上で、FastAPIにおける正しい非同期処理の実装についてまとめます。

対象読者

  • FastAPIでasync/awaitを書いているのに、処理が詰まって困っている人
  • プロセス、スレッド、イベントループの違いを、具体的な実機検証(psコマンドなど)で理解したい人
  • ApacheとNginxのアーキテクチャの違い、C10K問題について理解したい人

検証内容

前提・参考

  • 以下の検証手順で実施していく

    1. Dockerコンテナによる環境構築: 各Webサーバー(Apache / Nginx / FastAPI)をコンテナ上で起動する。(※アプリ側の負荷を排除し、サーバーの並行処理能力のみを比較するため、処理は単純なHTML返却とする)
    2. ベースラインの確認: 負荷をかける前のプロセス数・スレッド数の初期状態を ps コマンドで記録する。
    3. 負荷試験の実施: Locustを用い、最大300並列(10ユーザー/秒ずつ増加)の負荷を注入する。
    4. 負荷時の挙動観測: 負荷ピーク時におけるプロセス・スレッドの変化を ps コマンドで再確認し、初期状態と比較する。
  • psコマンドの見方

    略称 正式名称 (英語) 意味
    PID Process ID プロセスID。実行中のプログラムに割り振られる固有の識別番号です。
    PPID Parent Process ID 親プロセスID。そのプロセスを起動した「親」のPIDです。
    LWP Light Weight Process スレッドID。Linuxではスレッドのことを「軽量プロセス」と呼ぶため、この名称になっています。
    C CPU Utilization CPU使用率(の指標)。プロセスの生存期間中にどれくらいCPUを使ったかを示す整数値です。
    NLWP Number of Light Weight Processes スレッドの総数。そのプロセスの中にスレッドがいくつ存在するかを示します。
  • [参考記事]ApacheとNginxの違い

  • [参考記事]Apacheの方式の違い

→ Apacheについては複数のMPMがあるようで、preforkとeventで試しました。

  • [参考記事]C10K問題について

1. Webサーバーの進化に見る「並行処理」の変遷

まず、Apache(マルチプロセス & マルチスレッド)とNginx(シングルスレッド / イベントループ方式)の挙動を実機で検証しました。

Apache(prefork)(マルチプロセス)

Dokcerfile
```
# 1. 公式のApacheイメージをベースにする
FROM httpd:latest

# 2. 確認用の ps コマンドをインストール
RUN apt-get update && \\
  apt-get install -y procps && \\
  rm -rf /var/lib/apt/lists/*

# 3. 設定ファイルを書き換えて「Preforkモード」にする
RUN sed -i \\
  -e 's/^LoadModule mpm_event_module/#LoadModule mpm_event_module/' \\
  -e 's/^#LoadModule mpm_prefork_module/LoadModule mpm_prefork_module/' \\
  conf/httpd.conf

EXPOSE 80
```
初期状態のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-prefork ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 06:51 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1     8  0    1 06:51 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1     9  0    1 06:51 ?        00:00:00 httpd -DFOREGROUND
www-data    10     1    10  0    1 06:51 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    11  0    1 06:51 ?        00:00:00 httpd -DFOREGROUND
www-data    12     1    12  0    1 06:51 ?        00:00:00 httpd -DFOREGROUND
root        13     0    13  0    1 06:51 ?        00:00:00 ps -efL
```
300並列負荷時のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-prefork ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data     7     1     7  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1     8  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1     9  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    10     1    10  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    11  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    18     1    18  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    19     1    19  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    20     1    20  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    21     1    21  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    22     1    22  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    23     1    23  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    24     1    24  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    25     1    25  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    26     1    26  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    27     1    27  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    28     1    28  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    29     1    29  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    30     1    30  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    31     1    31  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    32     1    32  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    33     1    33  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    34     1    34  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    35     1    35  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    36     1    36  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    37     1    37  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    38     1    38  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    39     1    39  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    40     1    40  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    41     1    41  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    42     1    42  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    43     1    43  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    44     1    44  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    45     1    45  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    46     1    46  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    47     1    47  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    48     1    48  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    49     1    49  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    50     1    50  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    51     1    51  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    52     1    52  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    53     1    53  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    54     1    54  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    55     1    55  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    56     1    56  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    57     1    57  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    58     1    58  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    59     1    59  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    60     1    60  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    61     1    61  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    62     1    62  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    63     1    63  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    64     1    64  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    65     1    65  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    66     1    66  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    67     1    67  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    68     1    68  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    69     1    69  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    70     1    70  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    71     1    71  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    72     1    72  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    73     1    73  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    74     1    74  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    75     1    75  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    76     1    76  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    77     1    77  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    78     1    78  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    79     1    79  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    80     1    80  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    81     1    81  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    82     1    82  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    83     1    83  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    84     1    84  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    85     1    85  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    86     1    86  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    87     1    87  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    88     1    88  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    89     1    89  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    90     1    90  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    91     1    91  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    92     1    92  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    93     1    93  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    95     1    95  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    96     1    96  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    97     1    97  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    98     1    98  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data    99     1    99  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   100     1   100  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   101     1   101  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   102     1   102  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   103     1   103  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   104     1   104  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   105     1   105  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   106     1   106  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   107     1   107  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   108     1   108  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   109     1   109  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   110     1   110  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   111     1   111  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   112     1   112  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   113     1   113  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   114     1   114  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   115     1   115  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   116     1   116  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   117     1   117  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   118     1   118  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   119     1   119  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   120     1   120  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   121     1   121  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   122     1   122  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   123     1   123  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   124     1   124  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   125     1   125  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   126     1   126  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   127     1   127  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   128     1   128  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   129     1   129  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   130     1   130  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   131     1   131  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   132     1   132  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   133     1   133  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   134     1   134  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   135     1   135  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   136     1   136  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   137     1   137  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   138     1   138  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   139     1   139  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   140     1   140  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   141     1   141  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   142     1   142  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   143     1   143  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   144     1   144  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   145     1   145  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   146     1   146  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   147     1   147  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   148     1   148  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   149     1   149  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   150     1   150  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   151     1   151  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   152     1   152  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   153     1   153  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   154     1   154  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   155     1   155  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   156     1   156  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   157     1   157  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   158     1   158  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   159     1   159  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   160     1   160  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   161     1   161  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   162     1   162  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   163     1   163  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   164     1   164  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   165     1   165  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   166     1   166  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   167     1   167  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   168     1   168  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   169     1   169  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   170     1   170  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   171     1   171  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   172     1   172  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   173     1   173  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   174     1   174  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   175     1   175  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   182  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   183     1   183  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   184     1   184  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   185     1   185  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   186     1   186  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   188     1   188  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   189     1   189  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   190     1   190  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   191     1   191  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   192     1   192  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   193     1   193  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   194     1   194  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   195     1   195  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   196     1   196  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   197     1   197  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   198     1   198  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   199     1   199  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   200     1   200  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   201     1   201  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   203     1   203  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   204     1   204  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   205     1   205  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   206     1   206  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   207     1   207  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   208     1   208  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   209     1   209  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   210     1   210  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   211     1   211  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   212     1   212  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   213     1   213  0    1 07:02 ?        00:00:00 httpd -DFOREGROUND
www-data   238     1   238  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   245     1   245  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   246     1   246  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   259     1   259  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   260     1   260  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   261     1   261  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   262     1   262  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   275     1   275  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   276     1   276  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   277     1   277  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   278     1   278  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   279     1   279  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   280     1   280  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   281     1   281  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   282     1   282  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   295     1   295  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   296     1   296  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   297     1   297  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   298     1   298  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   299     1   299  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   300     1   300  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   301     1   301  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   302     1   302  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   303     1   303  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   304     1   304  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   305     1   305  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   306     1   306  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   307     1   307  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   308     1   308  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   309     1   309  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   310     1   310  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   322     1   322  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   323     1   323  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   324     1   324  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   325     1   325  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   326     1   326  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   327     1   327  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   328     1   328  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   329     1   329  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   330     1   330  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   331     1   331  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   332     1   332  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   333     1   333  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   334     1   334  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   335     1   335  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   336     1   336  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   337     1   337  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   338     1   338  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   339     1   339  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   340     1   340  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   341     1   341  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   342     1   342  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   343     1   343  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   344     1   344  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   345     1   345  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   346     1   346  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   347     1   347  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   348     1   348  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   349     1   349  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   350     1   350  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   351     1   351  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   352     1   352  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   353     1   353  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
www-data   377     1   377  0    1 07:03 ?        00:00:00 httpd -DFOREGROUND
root       532     0   532 20    1 07:03 ?        00:00:00 ps -efL
```
  • パフォーマンス

    image.png

  • 結果
    負荷に応じてPID(プロセスID)が次々と発行される=リクエストごとにプロセスが増加することが分かりました。

Apache(event)(マルチスレッド)

Dokcerfile
```
# 1. 公式のApacheイメージをベースにする
FROM httpd:latest

# 2. 確認用の ps コマンドをインストール
RUN apt-get update && \\
  apt-get install -y procps && \\
  rm -rf /var/lib/apt/lists/*

# 3. デフォルトの「Eventモード」とするため、モード変更は実施しない

EXPOSE 80
```
初期状態のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-multi-apache ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1     8  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    12  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    13  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    14  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    15  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    16  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    17  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    18  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    19  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    20  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    21  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    23  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    24  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    25  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    27  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    28  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    30  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    32  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    34  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    36  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    38  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    39  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    41  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    43  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    45  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    47  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    49  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1     9  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    29  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    31  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    33  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    35  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    37  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    40  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    42  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    44  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    46  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    48  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    50  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    51  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    52  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    53  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    54  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    55  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    56  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    57  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    58  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    59  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    60  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    61  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    79  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    80  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    81  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    82  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    11  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    62  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    63  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    64  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    65  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    66  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    67  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    68  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    69  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    70  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    71  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    72  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    73  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    74  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    75  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    76  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    77  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    78  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    83  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    84  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    85  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    86  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    87  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    88  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    89  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    90  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    91  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
root        92     0    92 16    1 06:58 ?        00:00:00 ps -efL
```
300並列負荷時のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-multi-apache ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1     8  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    12  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    13  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    14  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    15  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    16  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    17  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    18  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    19  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    20  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    21  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    23  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    24  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    25  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    27  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    28  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    30  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    32  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    34  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    36  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    38  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    39  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    41  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    43  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    45  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    47  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     8     1    49  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1     9  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    29  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    31  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    33  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    35  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    37  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    40  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    42  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    44  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    46  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    48  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    50  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    51  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    52  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    53  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    54  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    55  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    56  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    57  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    58  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    59  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    60  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    61  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    79  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    80  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    81  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data     9     1    82  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    11  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    62  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    63  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    64  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    65  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    66  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    67  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    68  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    69  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    70  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    71  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    72  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    73  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    74  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    75  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    76  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    77  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    78  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    83  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    84  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    85  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    86  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    87  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    88  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    89  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    90  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data    11     1    91  0   27 06:58 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   182  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   184  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   185  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   186  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   187  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   188  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   189  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   190  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   191  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   192  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   193  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   194  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   195  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   196  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   197  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   198  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   199  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   200  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   201  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   202  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   203  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   204  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   205  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   206  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   207  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   208  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   182     1   209  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   222  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   224  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   225  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   226  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   227  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   228  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   229  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   230  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   231  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   232  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   233  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   234  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   235  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   236  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   237  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   238  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   239  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   240  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   241  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   242  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   243  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   244  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   245  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   246  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   247  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   248  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   222     1   249  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   263  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   266  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   268  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   269  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   270  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   274  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   276  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   283  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   284  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   285  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   286  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   287  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   288  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   289  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   290  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   291  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   292  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   294  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   296  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   298  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   299  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   300  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   302  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   303  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   305  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   306  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   263     1   308  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   264  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   271  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   272  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   273  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   275  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   277  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   278  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   279  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   280  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   281  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   282  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   293  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   295  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   297  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   301  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   304  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   307  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   309  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   310  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   311  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   312  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   313  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   314  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   315  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   316  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   317  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
www-data   264     1   318  0   27 07:00 ?        00:00:00 httpd -DFOREGROUND
root       498     0   498  0    1 07:00 ?        00:00:00 ps -efL
```
  • パフォーマンス

image.png

  • 結果
    負荷に応じてPID(プロセスID)とそれに紐づく27スレッドが発行される=リクエストのたびにプロセスを作るのではなく、捌ききれなくなったタイミングでスレッドの束(1プロセス単位)をまとめて追加することが分かりました。また、スレッドが一気に増える分、パフォーマンスもpreforkよりも改善されました。

Nginx(シングルスレッド / イベントループ方式)

Dokcerfile
```
# 1. 公式のNginxイメージをベースにする
FROM nginx:latest

# 2. 確認用の ps コマンドをインストール
RUN apt-get update && \\
  apt-get install -y procps && \\
  rm -rf /var/lib/apt/lists/*

EXPOSE 80
```
初期状態のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-nginx ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 07:08 ?        00:00:00 nginx: master process nginx -g daemon off;
nginx       29     1    29  0    1 07:08 ?        00:00:00 nginx: worker process
nginx       30     1    30  0    1 07:08 ?        00:00:00 nginx: worker process
root        31     0    31 20    1 07:08 ?        00:00:00 ps -efL
```
300並列負荷時のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-nginx ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 07:08 ?        00:00:00 nginx: master process nginx -g daemon off;
nginx       29     1    29  0    1 07:08 ?        00:00:00 nginx: worker process
nginx       30     1    30  0    1 07:08 ?        00:00:00 nginx: worker process
root       218     0   218 16    1 07:10 ?        00:00:00 ps -efL
```
  • パフォーマンス

image.png

  • 結果
    300多重の状態でも、起動時の2プロセスから増えることはなかった=今回の単純なHTML返却の処理では、少数の固定プロセスで捌き切れることが分かりました。パフォーマンスについても、Apacheのマルチスレッドとほぼ同等のパフォーマンスとなりました。

ApacheとNginxのまとめ

比較項目 Apache (prefork)
【マルチプロセス】
Apache (event)
【マルチスレッド】
Nginx
【シングルスレッド / イベントループ】
プロセス・スレッドの動き リクエストごとにプロセスが増加。
1つのプロセスが1つの接続を専有する(プロセス=メインスレッド)。
プロセスごとに複数のスレッドを保持。
初期状態で3プロセス(各27スレッド、計81スレッド)が起動。不足するとプロセス単位で増える。
少数の固定プロセスで動作。
1プロセス1スレッドで動作し、今回の300多重負荷でもプロセス・スレッド数に変化なし。
今回の検証結果 負荷に応じてPID(プロセスID)が次々と発行された。 負荷に応じてNLWP(スレッド数)がプロセス内で管理された。 300多重の状態でも、起動時の2プロセスから増えることはなかった。

2. FastAPI(シングルスレッド)で同期処理、非同期処理の動きを試す

ApacheとNginxの比較を通じて、少数の固定リソースで効率的にリクエストを捌く「イベントループ方式(Nginx)」の優位性が確認できました。FastAPI(Uvicorn)も、このNginxと同様のアーキテクチャを採用しています。

しかし、イベントループ方式には「1つの処理がスレッドを占有(ブロッキング)してしまうと、後続のすべての処理が止まる」という弱点があります。

ここでは、FastAPIにおいて「同期処理(time.sleep)」と「非同期処理(await asyncio.sleep)」を実行した際、イベントループの並行処理能力にどのような差が出るかを、実機ログとあわせて検証します。

fastapi(同期処理)

コード
```
app = FastAPI()

@app.get("/")
async def read_root():
    print("リクエストを受け付けました。3秒待機します...")

    time.sleep(3)

    print("3秒待機が完了しました。レスポンスを返します。")
    return {"message": "hello"}
```
Dokcerfile
```
FROM python:3.11-slim

WORKDIR /app

RUN apt-get update && \\
  apt-get install -y procps && \\
  rm -rf /var/lib/apt/lists/*

# 最小限のライブラリをインストール
RUN pip install --no-cache-dir fastapi uvicorn

# ソースコードをコピー
COPY main.py .

# ワーカー数を「1」にして起動
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80", "--workers", "1"]
```
初期状態のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-fastapi ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  7    1 01:25 ?        00:00:00 /usr/local/bin/python3.11 /usr/local/bin/uvicorn main:app --host 0.0.0.0 --port 80 --workers 1
root         7     0     7  0    1 01:25 ?        00:00:00 ps -efL
```
10並列負荷時のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-fastapi ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 01:25 ?        00:00:00 /usr/local/bin/python3.11 /usr/local/bin/uvicorn main:app --host 0.0.0.0 --port 80 --workers 1
root        18     0    18  0    1 01:29 ?        00:00:00 ps -efL
```
  • パフォーマンス(10多重10users/second)

image.png

ログ
```
$ docker logs -f demo-fastapi
INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on <http://0.0.0.0:80> (Press CTRL+C to quit)
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:60970 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:60980 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:60988 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:60990 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:60994 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:32776 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:32784 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:32796 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:32808 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:32810 - "GET / HTTP/1.1" 200 OK

...

リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:32810 - "GET / HTTP/1.1" 200 OK
```
  • 結果
    ログが「3秒に1回」しか出力されていない=1人が待っている間、サーバー全体がフリーズしている状態ということが分かりました。

fastapi(非同期処理)

コード
```
@app.get("/")
async def read_root():
    print("リクエストを受け付けました。3秒待機します...")

    await asyncio.sleep(3)

    print("3秒待機が完了しました。レスポンスを返します。")
    return {"message": "hello"}
```
Dokcerfile
```
FROM python:3.11-slim

WORKDIR /app

RUN apt-get update && \\
  apt-get install -y procps && \\
  rm -rf /var/lib/apt/lists/*

# 最小限のライブラリをインストール
RUN pip install --no-cache-dir fastapi uvicorn

# ソースコードをコピー
COPY main.py .

# ワーカー数を「1」にして起動
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80", "--workers", "1"]
```
初期状態のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-fastapi ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  5    1 01:29 ?        00:00:00 /usr/local/bin/python3.11 /usr/local/bin/uvicorn main:app --host 0.0.0.0 --port 80 --workers 1
root         7     0     7  0    1 01:29 ?        00:00:00 ps -efL
```
10並列負荷時のプロセス・スレッド状況(psコマンド)
```
$ docker exec demo-fastapi ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 01:29 ?        00:00:00 /usr/local/bin/python3.11 /usr/local/bin/uvicorn main:app --host 0.0.0.0 --port 80 --workers 1
root        19     0    19  0    1 01:31 ?        00:00:00 ps -efL
```
  • パフォーマンス(10多重10users/second)

image.png

ログ
```
$ docker logs -f demo-fastapi
INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on <http://0.0.0.0:80> (Press CTRL+C to quit)
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49646 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49658 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49672 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49680 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49688 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49702 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49704 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49718 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49720 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49724 - "GET / HTTP/1.1" 200 OK
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
リクエストを受け付けました。3秒待機します...
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49658 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49720 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49672 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49646 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49704 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49702 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49688 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49680 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49724 - "GET / HTTP/1.1" 200 OK
3秒待機が完了しました。レスポンスを返します。
INFO:     172.17.0.1:49718 - "GET / HTTP/1.1" 200 OK

...
```
  • 結果
    ログに「リクエスト受付」が一気に表示される=3秒待っている間に、次のリクエストをどんどん受け付けられている状態ということが分かりました。

まとめ:並行処理モデルの比較

今回の結果を元に、マルチプロセス、マルチスレッド、非同期 (イベントループ)の違いをAIにまとめてもらいました。また、FastAPIでは実装時にasync/awaitの記載が必須でしたが、Goroutine等ではその辺の実装も改善されているらしく、それらの軽量スレッドについても表に追加してもらいました。

特徴 マルチプロセス (Fork) マルチスレッド 非同期 (イベントループ) 軽量スレッド (現代)
基本単位 プロセス (Process) スレッド (Thread) イベント / タスク 仮想スレッド / Goroutine
コードの書き味 直感的
普通の逐次処理
直感的
ただし排他制御が必要
技巧的
async/awaitが必須
理想的
同期の書き味+非同期の性能
特長 最強の隔離性
1つのクラッシュが他に影響せず、メモリも完全独立。
高速なデータ共有
メモリ空間を共有し、大量データのコピーが不要。
圧倒的な並行数
1スレッドで数万の接続を管理。メモリ消費が最小。
開発効率と性能の融合
可読性を保ったまま限界性能を引き出す。
リソース消費 非常に大きい
OSがプロセスごとに大量のメモリを確保。
中程度
スレッドごとにスタック(約1MB)を確保。
極めて小さい
接続情報のみ保存。オーバーヘッドがほぼ無い。
極めて小さい
スタックを動的に変えるため数KBから動作。
CPUの動き 切替時にOSの重い介入(コンテキストスイッチ)が入る。 OSが切り替えるが、プロセスよりは軽快。 1人が「待ち」の間に次々仕事。CPUの空きを無くす。 ランタイムが裏で効率的に「待ち」をスキップする。
主な課題 大量のリクエストでメモリ不足に陥りやすい。 競合状態 (Race)
変数の書き換え順序でバグが出やすい。
CPUヘビーな処理
1人が重い計算を始めると全員の足が止まる。
デバッグ時に裏側のスケジューリングが見えにくい。
代表的な採用例 PHP (Apache/FPM), PostgreSQL Java (Platform Thread), C++, Ruby (Parallel) Node.js (JavaScript), Python (asyncio), Nginx Go (Goroutine), Java 21+ (Virtual Threads), Elixir (Process)

結論

ApacheとNginxの並行処理モデルを比較したことで、Webサーバーが大量のリクエストを効率的に捌くために、どのような歴史を辿り、アーキテクチャが変遷してきたのかを深く理解することができました。

この学習を通じて、FastAPIの非同期処理のポテンシャルを引き出すには、実装側でイベントループを意識した適切な制御を行うことが不可欠であると痛感しました。

今後はライブラリの表面的な使い方だけでなく、OSのプロセスやスレッドといった低レイヤーの挙動も意識した、一歩踏み込んだ実装を心がけていきたいと思います。

補足

WSGIとASGI

FastAPIでは非同期のみ取り上げましたが、PythonにもWebサーバーとWebアプリケーション(プログラム)を繋ぐためのインターフェース(NginxやUvicornといったサーバーの違いを意識せずにプログラムを書くためのもの)として、同期と非同期のどちらの処理方法もあるようで、フレームワークによって採用している規格が異なるようでした。

特徴 WSGI (Web Server Gateway Interface) ASGI (Asynchronous Server Gateway Interface)
設計思想 同期・ブロッキング 非同期・ノンブロッキング
対応モデル Apache (prefork/worker) に近い Nginx (イベントループ) に近い
並行処理 1リクエスト = 1プロセス/スレッド 1スレッドで大量のリクエストを多重化
得意分野 伝統的なCRUD操作、安定性重視 API呼び出し、WebSocket、チャット
代表的なFW Django, Flask FastAPI, Starlette, Sanic
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?