1
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?

More than 1 year has passed since last update.

サーバーアプリケーションとnginx unit

Last updated at Posted at 2024-03-18

ブートキャンプで学生たちを相手にしていると、バックエンドでサーバーアプリケーションを立ち上げる方法について混乱が多いため、ここに整理する。

ここではnginx Unitを使います。以前では私が誤って考えていたこともあり、nginx unitの技術の真価を十分に理解していなかったと感じたため、再びここに整理することにしました。

サーバープロセスの起動方法の基本

サーバープロセスを起動する基本は「バックグラウンド」で実行することです。例えば、Spring Bootの配布jarファイルを起動する場合は

$ java -jar build/libs/application.jar &

のようにして「&」を付けてバックグラウンドで起動するのです(いわゆるnohub起動)。

このように起動するとどのような問題があるでしょうか?

  • プロセスの管理が難しい。
    • 別の管理ツールがなければ、プロセス管理の基本はログを見ることになりますが、ログはアプリケーションから別途に残す必要があります。職人技でログの生成や保存を実装する必要があります。
  • オートスケーリング
    • 負荷が発生した場合は、プロセスの数を増やすか、負荷が減少したらプロセスの数を減らす必要があります。これも管理ツールがなければ困難な部分です。

ここで目立つのは動的構成と含まれるプロセス管理機能です。負荷が増加すると自動でスケーリングを行い、これもオプションで調整可能です

nginx unitのインストール

nginx unitのインストールはmacOSおよびほとんどのLinuxをサポートしています。

インストールの詳細は公式ウェブサイトを参照すれば良いですが、注目すべき点はunitのメインとパッケージをインストールする必要があるということです。例えば、ubuntu 20.04(筆者が使用しているバージョン)の場合のインストールコマンドは次のようになります。

sudo apt update
sudo apt install unit
sudo apt install unit-dev unit-jsc11 unit-perl  \
      unit-php unit-python3.8 unit-ruby unit-wasm
sudo systemctl restart unit

(もしubuntu20.04でpython3.11をインストールされてもunit-python3.11パッケージを設置はできません。defaultバージョンはpython3.8なのでunit-python3.8のみできます。)

ここでのunit-dev, unit-jsc11, unit-python3.8などは、それぞれ汎用、Java11、Perl、Python3.8のプロセスをunitで管理するという意味です。

Nest.jsをunitで実行する

よく使われるフレームワーク(Spring Boot、Flaskなど)や言語については、すでに公式ウェブサイトに設定方法が記載されています。ここでは、公式ウェブサイトには記載されていないNest.jsをunitで実行する方法について説明します。

nest.jsテストプロジェクトのフォルダです。

~/nestjs/tddtest$ ll

total 396
drwxr-xr-x   7 ubuntu ubuntu   4096 Mar  5 06:03 ./
drwxrwxr-x   3 ubuntu ubuntu   4096 Nov  2 05:16 ../
-rwxr-xr-x   1 ubuntu ubuntu    663 Nov  2 05:16 .eslintrc.js*
drwxr-xr-x   7 ubuntu ubuntu   4096 Nov  2 05:16 .git/
-rwxr-xr-x   1 ubuntu ubuntu    391 Nov  2 05:16 .gitignore*
-rwxr-xr-x   1 ubuntu ubuntu     51 Nov  2 05:16 .prettierrc*
-rwxr-xr-x   1 ubuntu ubuntu   3340 Nov  2 05:16 README.md*
drwxrwxr-x   2 ubuntu ubuntu   4096 Mar  5 05:29 dist/
-rwxr-xr-x   1 ubuntu ubuntu    171 Nov  2 05:16 nest-cli.json*
drwxr-xr-x 485 ubuntu ubuntu  20480 Mar  5 04:39 node_modules/
-rwxr-xr-x   1 ubuntu ubuntu 325381 Nov  2 05:16 package-lock.json*
-rwxr-xr-x   1 ubuntu ubuntu   1948 Nov  2 05:16 package.json*
drwxr-xr-x   2 ubuntu ubuntu   4096 Mar  5 05:25 src/
drwxr-xr-x   2 ubuntu ubuntu   4096 Nov  2 05:16 test/
-rwxr-xr-x   1 ubuntu ubuntu     97 Nov  2 05:16 tsconfig.build.json*
-rwxr-xr-x   1 ubuntu ubuntu    638 Nov  3 04:11 tsconfig.json*

我々が興味があるのは/distフォルダです。

~/nestjs/tddtest/dist$ ll
-rw-rw-r-- 1 ubuntu ubuntu    181 Mar  5 05:25 app.controller.d.ts
-rw-rw-r-- 1 ubuntu ubuntu   1595 Mar  5 05:25 app.controller.js
-rw-rw-r-- 1 ubuntu ubuntu    428 Mar  5 05:25 app.controller.js.map
-rw-rw-r-- 1 ubuntu ubuntu     35 Mar  5 05:25 app.module.d.ts
-rw-rw-r-- 1 ubuntu ubuntu   1146 Mar  5 05:25 app.module.js
-rw-rw-r-- 1 ubuntu ubuntu    351 Mar  5 05:25 app.module.js.map
-rw-rw-r-- 1 ubuntu ubuntu    104 Mar  5 05:25 app.service.d.ts
-rw-rw-r-- 1 ubuntu ubuntu   2855 Mar  5 05:25 app.service.js
-rw-rw-r-- 1 ubuntu ubuntu    863 Mar  5 05:25 app.service.js.map
-rw-rw-r-- 1 ubuntu ubuntu    193 Mar  5 05:25 constants.d.ts
-rw-rw-r-- 1 ubuntu ubuntu    363 Mar  5 05:25 constants.js
-rw-rw-r-- 1 ubuntu ubuntu    265 Mar  5 05:25 constants.js.map
-rw-rw-r-- 1 ubuntu ubuntu     11 Mar  5 05:25 main.d.ts
-rw-rw-r-- 1 ubuntu ubuntu    340 Mar  5 05:25 main.js
-rw-rw-r-- 1 ubuntu ubuntu    287 Mar  5 05:25 main.js.map
-rw-rw-r-- 1 ubuntu ubuntu 108543 Mar  5 05:25 tsconfig.build.tsbuildinfo
-rw-rw-r-- 1 ubuntu ubuntu    143 Mar  5 05:25 user.json

Nest.jsでは、メインエントリーファイルはmain.jsであり、デプロイフォルダーを実行するにはnode main.jsコマンドでプロセスを起動しますが、これをnginx unitで実行する方法について説明します。

まずconfig.json(ファイル名はなんでもいいです。)を作成します。

{
    "listeners": {
        "*:4000": {
            "pass": "applications/nestjs_app"
        }
    },

    "applications": {
        "nestjs_app": {
            "type": "external",
            "working_directory": "/home/ubuntu/nestjs/tddtest/dist",
            "executable": "/usr/bin/env",
            "arguments": [
                    "node",
                    "--loader",
                    "unit-http/loader.mjs",
                    "--require",
                    "unit-http/loader",
                    "main.js"
            ]

        }
    }
}

このファイルを簡単に説明すると、4000番ポートを使用し、typeは「external」に、working_directoryは「dist」フォルダに設定します。executableはenv(/usr/bin/env)にして、argumentを通じてnodeコマンド及びmain.jsファイルの起動を設定します。

これは次のコマンドを通じて反映されます(ubuntu Linuxを基準としています。他のOSの場合は公式ウェブサイトを参照してください)。

$ sudo curl -X PUT --data-binary @config.json --unix-socket\
/var/run/control.unit.sock http://localhost/config

成功すると、次のように表示されます。

{
        "success": "Reconfiguration done."
}

プロセスが起動されたか確認してみましょう。

~$ ps -ef | grep unit
root      196630       1  0 05:17 ?        00:00:00 unit: main v1.32.0 [unitd]
unit      196632  196630  0 05:17 ?        00:00:00 unit: controller
unit      196633  196630  0 05:17 ?        00:00:00 unit: router
unit      196799  196630  0 05:31 ?        00:00:00 unit: "nestjs_app" prototype
unit      196800  196799  0 05:31 ?        00:00:00 node --loader unit-http/loader.mjs --require unit-http/loader main.js
  1. unit: main [unitd]
    これはNginx Unitのメインプロセスで、全体のシステムの管理と調整を担当します。起動時に初期化を行い、その後は他のプロセスの実行を管理します。
  2. unit: controller
    コントローラープロセスは、Nginx Unitの設定および管理APIリクエストを処理します。このプロセスは、新しい設定変更を受け取り、それらの変更をシステムに適用する役割を果たします。
  3. unit: router
    ルータープロセスは、入ってくるリクエストを適切なアプリケーションプロセスに転送する役割を果たします。リクエストのURL、ヘッダーなどを分析し、設定されたルールに従ってどのアプリケーションにリクエストを転送するかを決定します。
  4. unit: “nestjs_app” prototype
    プロトタイププロセスは、特定のアプリケーション(この場合は“nestjs_app”)の初期インスタンスを作成します。このプロトタイプは、実際のリクエスト処理用のアプリケーションプロセスを作成するために使用されるテンプレートとして機能します。新しいリクエストが到着し、追加のプロセスが必要な場合、このプロトタイプを基にアプリケーションプロセスが作成されます。
  5. unit: “nestjs_app” application
    アプリケーションプロセスは、実際に入ってくるウェブリクエストを処理します。“nestjs_app”プロセスは、Nodeアプリケーションのコードを実行してリクエストに応答します。このプロセスは、必要に応じて動的に作成および終了されることがあり、各インスタンスは別々のリクエストを独立して処理できます。

このようにすると、unitdプロセスが全体的にnestjs_appを管理しながらスケーリングなどを調整することができます。スケーリングテストの部分は、後で再度取り上げることにします。

4000番ポートで実行した結果は以下の通りです。

1
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
1
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?