Nginxについてまとめてみた

## はじめに
現在、ポートフォリオとしてRailsを使って簡易的なSNSアプリを開発しています。
開発を進める中でリバースプロキシにNginxを使うことにしたのですが、Nginxが何者なのかよくわからないまま使ったせいで導入に苦労してしまいました。
そこで、本記事ではNginxおよび関連知識について自分なりに調べたことをまとめました。

## 目次
[1. Nginxとは](#nginxとは)
[2. Nginxのアーキテクチャ](#nginxのアーキテクチャ)
[3. configファイルの基礎知識](#configファイルの基礎知識)

## Nginxとは
- LinuxなどのOS上で動作するWebサーバーソフトウェア
- コンピュータの構成要素ではミドルウェアにあたる
- リバースプロキシ、ロードバランサー、WAF、APIゲートウェイなどの機能を持つ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625095/5314c58a-4022-d99c-7713-66e91c50c07d.png" width="70%">

**＜用語をざっくり解説＞**
<details>
<summary>Webサーバー</summary>

- クライアントからのリクエストに応じてWebページなどのコンテンツを返すソフトウェア
- Webアプリのホスティング、アクセス制御、セキュリティ、パフォーマンスの最適化などの機能を持つ
</details>

<details>
<summary>リバースプロキシ</summary>

- クライアントからのリクエストを受け取り、サーバーに転送する役割をもつ
- サーバーへのアクセスを制御し、セキュリティやパフォーマンスを向上させることができる
</details>

<details>
<summary>ロードバランサー</summary>

- 外部からのアクセスを複数のサーバーへ分散させるソフトウェア
- 負荷分散させることで可用性を向上させることができる
</details>

<details>
<summary>WAF</summary>

- Web Application Firewallの略称
- Webアプリへの不正アクセスや攻撃から保護するセキュリティツール
</details>

<details>
<summary>APIゲートウェイ</summary>

- クライアントとバックエンドのAPIサービスとの間に位置する管理ツール
- APIエンドポイントへのアクセス管理、セキュリティ管理、トラフィック制御などの機能を持つ
</details>

## Nginxのアーキテクチャ
Nginxのアーキテクチャは以下の特徴を持つ。
- マルチプロセス・シングルスレッドで動作する
- イベント駆動により各プロセスが複数のクライアントからのリクエスト・レスポンスを並行して処理することができる
- リクエスト・レスポンスの処理に伴うI/O処理を並行かつ高速に行うため多重I/OやノンブロッキングI/Oを活用している

**＜プロセスの構成＞**
NginxではMaster Processとその子プロセスであるWorker processが起動している。
- Master Process => Nginx全体のプロセスをコントロール
- Worker Process => クライアントからのリクエスト・レスポンスを処理

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625095/304a22fd-2ba0-384a-04d0-eb9f263e2401.png" width="80%">

※キャッシュを利用する場合はキャッシュを管理するCache manager、キャッシュを読み込むCache loaderというプロセスがあるが今回は省略している。

**＜用語をざっくり解説＞**
<details>
<summary>プロセスとスレッド</summary>

- プロセスはプログラムの実行単位であり、プロセス毎にプログラム実行に必要なリソース（メモリなど）を確保している
- スレッドは、プロセス内で実行される軽量な実行単位で同じプロセス内のスレッドはリソースを共有している
- [:page_facing_up:プロセスとスレッドの解説記事](https://zenn.dev/antez/books/568dd4d86562a1/viewer/531a45)
</details>

<details>
<summary>多重I/O</summary>

- 複数のI/O処理を同時に管理する方法
- Linux上のNginxではepollというI/Oイベント通知機能を使って、複数のI/Oを効率的に管理している
</details>

<details>
<summary>ノンブロッキングI/O</summary>

- I/O処理が完了するまで待つ状態をブロッキングという
- ノンブロッキングI/OではI/O操作待ちの状態となったとき、即座にアプリケーション側にエラーを返す
- エラーを受け取った場合、アプリケーションは他の処理を行い、しばらくしてからI/O処理をリトライすることでI/O操作を効率的に行う
</details>

## configファイルの基礎知識
### configファイルの場所
初期設定では2つのファイルがある。
- `etc/nginx/nginx.conf`
  => メインの設定ファイルでworkerプロセスやエラーログなどの基本設定を行う。
- `etc/nginx/conf.d/default.conf`
  => デフォルトで動作するWebサーバーの設定を行う。nginx.conf内でincludeさせる。

### Context
configファイルの中はcontextという単位で設定が書かれており、以下のような階層構造となっている。
```
main
├── events
├── http
│   └── server
│       └── location
└── stream
    └── server
```

<details>
<summary>main context</summary>

- Worker processの数
- エラーログの出力先
- 動的モジュールのロード
- 実行ユーザー名の設定
- Process IDファイルの場所
</details>

<details>
<summary>events context</summary>

- Workrer procesごとのコネクション数を記述
- 基本的にはデフォルトのまま使用
</details>

<details>
<summary>http context</summary>

- HTTPコネクションをどのように処理するか定義
- Access logの出力先とフォーマットを定義
- Locationを定義
</details>

<details>
<summary>server context</summary>

- リクエストに応答する仮想サーバーを指定
- ドメイン名の設定
- IPアドレス、ポートの設定
- SSL/TLS証明書/鍵の指定
- sslプロトコルやciphersの設定
</details>

<details>
<summary>location context</summary>

- server contextで受け取ったHTTPリクエストをどのように処理するか定義
  - httpのバージョン
  - URIの書き換え
  - PATHによる制御
  - HTTPヘッダの制御
  - どのupstreamにリクエストを渡すか
</details>

<details>
<summary>stream context</summary>

- ロードバランシングやリバースプロキシなどの設定に使う
- バックエンドサーバーへのアップストリーム接続を定義
</details>

### Directive
各contextでは、下記のようにdirectiveを使ってnginxの動作などを記載する。
- directiveはcontextをブロック`{}`で囲んだ中に記載する
- directiveはセミコロン`;`で終了する
```
Server {
	listen 80 http;             # listen directive
	root /usr/share/nginx/html; # root directive
}
```
実際にどのような設定を記述するかについては触れません。
詳細は詳細は公式ドキュメントを参照してくださいm(_ _)m
- [:page_facing_up:Nginx公式ドキュメント](https://nginx.org/en/docs/)
- [:page_facing_up:Nginx公式ドキュメント（日本語訳）](https://mogile.web.fc2.com/nginx/index.html)

## まとめ
今回はNginxを使う上で最低限知っておきたいことをまとめました。
自分はNginxがどんなものなのかよく知らないままリバースプロキシとして使おうとして苦労してしまいました。今後、新しいツールを使う時はそれがどのような仕組みで動いているのかアーキテクチャを理解するようにしたいと思います。

最後までお読みいただきありがとうございます！

## 参考資料
- [『達人が教えるWebパフォーマンスチューニング〜ISUCONから学ぶ高速化の実践』 6章](https://gihyo.jp/book/2022/978-4-297-12846-3)
- [Youtube動画：NGINXとは~基礎編～ | 東京エレクトロンデバイス](https://www.youtube.com/watch?v=-nRRZSsgEGc&t=1856s)