5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Nginxのworkerの設定メモ

Last updated at Posted at 2021-07-17

いつも忘れるので、nginxの自分用のメモを残します。

Nginxの設定の参考資料はnginx実践ガイド
動作の確認のため、負荷テストツールで負荷をかけてみてみます。ツールはJMeterを使用します。
環境は、コンテナでたてます。

Nginxの構造

Nginxは、Webサーバやロードバランサー、リバースプロキシサーバとして使うことができるOSSです。

Nginxはイベント駆動モデルと呼ばれるアーキテクチャで、HTTPリクエストを1プロセス1スレッドで処理しています。
masterプロセスとworkerプロセスがあり、masterプロセスは、設定ファイルの読み込み、ネットワークの通信に使うソケットの待ち受けを設定し、workerの起動と監視を行います。
workerプロセスは、ネットワーク処理のイベントループを処理し、masterが設定したソケットを使って接続を受け付け、ネットワークやファイルI/Oを実施します。HTTPやSSL/TLSのプロトコル処理もworkerの仕事です。
workerは内部で非同期I/Oの多重化、ノンブロッキングI/Oの多重化をしており、1つのプロセスで複数のリクエストを並行して処理できるようになっています。一方でファイルI/Oはデフォルトでは多重化しないようで、ファイルI/Oがボトルネックになることがあるようです。ここら編は設定で変えることができるようです。

最近、Webサーバのシェア率でApacheを抜いたそうですね。

準備

Nginxコンテナの設定

docker-compose.yaml
version: "3.9"

services:
  web:
    image: nginx:latest
    container_name: my-webapp
    volumes:
      - ./web/nginx.conf:/etc/nginx/nginx.conf
      - ./web/my-webapp.conf:/etc/nginx/conf.d/my-webapp.conf
      - ./web/html:/usr/share/nginx/html
    ports:
      - 8081:8080
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G

コンテナはCPU1コア、メモリ1Gで設定します。

・ログ
サーバの内部統計情報を出すため、下記の設定をします。

my-webapp.conf
server {
  listen 8080 default_server;

  location /stub_status {
    stub_status;
    access_log off;
    allow 127.0.0.1;
    deny all;
  }
}

これをして、/stub_statusにアクセスすると
2021-06-20_13-58.png
接続情報などが見れます。
レスポンスにかかった時刻は、

nginx.conf
http {
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" $request_time';
  access_log  /dev/stdout main;
}

こうするとログに出てきます。
2021-06-20_21-36.png

なお、Apache JMeterは他者様の記事を参考に設定します。
ここまでが計測のための準備。

workerの設定

いくつか設定値はありますが、重要なのは下記

worker_processes:workerのプロセス数、基本的にCPUのコア数
worker_connections:1つのworkerの最大接続数、1コネクションが1接続を担当
worker_rlimit_nofile:1つのworkerのファイルディスクリプタ の上限値

ファイルディスクリプタとは、ファイルを識別をする目印で、OSで限界値が設定されています。/proc/sys/fs/file-maxなどに書かれていて、この限界値を超えるとエラーになります。

そのため、設定値的には

ファイルディスクリプタの限界値 > worker_processes×worker_rlimit_nofile

となります。1プロセスで、worker_connections数の接続があるため、
実際は、

ファイルディスクリプタの限界値 > worker_processes×worker_rlimit_nofile
worker_rlimit_nofile > worker_connections×接続されて使うファイルディスクリプタ数

となります。
他者様の記事によると、ソケットファイルやコンテンツファイル、バックエンド側で使うものなどを踏まえて、3~4倍がいいらしいですが、余裕を持ってもっと大きくてもよさそうです。

また、同時に接続できる数は

同時に接続できる数 = worker_processes×worker_connections

になります。
ファイルディスクリプタの限界値からworker_connection数の限界値はわかりましたが、CPUやメモリは一応どんな感じかも考えます。

ルートパスにきたリクエストにたいして、HTMLだけを返すように設定して、

# Nginxコンテナ
resources:
  limits:
    cpus: '0.10'
    memory: 1G

# Nginx
worker_connections:2048
worker_processes:1

# ApacheJMeter
スレッド数:15000
Ramp-Up期間(秒):1
ループ回数:1

とした時、CPU使用率が10%(コンテナの限界値)になり、いくつかのリクエストが失敗していました。
これは

・CPU使用率が100%
→workerが限界まで動いた(worker_connectionsの分でリクエストを処理したら100%使った)
・いくつかのリクエストが失敗
→リクエストをさばけるキャパがなかった(worker_connectionsが足りない)

ということになるかと思います。
この場合、
対応できなかったリクエストに対応するためにworker_connectionを増やしても、CPU使用率が100%で処理が間に合わないので、単純にサーバの処理能力不足といえます。別サーバなどでNginxサーバを立てて負荷を分散する必要があります。
逆に、CPU使用率がそこまで高くなっていないのにリクエストが失敗していれば、サーバの処理は限界ではないのに、worker_connectionが足りないということが言えるかと思います。メモリ不足も同じで、サーバの処理能力的に不足しているということになるかと思います。

ただ、これはNginxだけを使った場合の話で、実際は後ろでアプリケーションが動き、同じサーバの場合はそちらのメモリ使用量やCPU使用率も考慮する必要があります。
このあたりは実際のアプリケーションで、負荷テストを行い、どのくらいのリクエストがさばけるのか確認する必要があります。
まとめると、

同時にさばけるリクエスト数を上げる
→worker_connectionsを高くする

CPU使用率やメモリ使用量が限界値をこえている
→別サーバなどでnginxサーバをたてて負荷分散する(+worker_connectionsも高すぎる疑惑)

CPU使用率やメモリ使用量がそこまで高くなっていないのにリクエストが失敗している
→worker_connectionsが低い

参考

nginx実践ガイド

Nginxのアーキテクチャを理解する

【Nginx】イベント駆動アーキテクチャとは

5
6
1

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
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?