saba1024のブログ

どうでも良い思いついた事とかプログラミング関係のメモとか書いていきます。

Nginx Unitを試してみた

最近リリースされた、Nginx Unitを試してみました。

インストール

こういう新しいツールを試すのにはやっぱりDockerですね!
とうことで、Docker上にNginx Unitをインストールして見ます。 今回はUbuntuで試してみました。

# デタッチモードで起動
sudo docker run -itd --name nginx-unit -p 8300:8300 ubuntu
# Dockerコンテナにアクセス
sudo docker exec -it nginx-unit bash

Dockerコンテナにアクセスできたら、まず必要なライブラリをインストールします。

root@88e2db6c51bc:~#apt-get update
root@88e2db6c51bc:~#apt-get install -y wget vim

インストールが完了したら、基本的には公式リポジトリのREADME通りに勧めるだけでOKです。
なお、今回はソースからコンパイルではなく、apt-getを使ってNginx Unitをインストールします。

root@88e2db6c51bc:~# cd
root@88e2db6c51bc:~# wget http://nginx.org/keys/nginx_signing.key
root@88e2db6c51bc:~# apt-key add nginx_signing.key
OK

/etc/apt/sources.listに以下の2行を追加。

deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx

これで準備完了です。後はapt-getで普通にインストールできます。

apt-get update
apt-get install unit

起動と停止

service unitd [start | stop]

Unit の設定

READMEを読む限り、全てAPI経由でNginxUnitサーバの設定を行うようです。
ということで、先ずはNginx Unitを起動しておきます。

service united start

Unitdが起動したら、以下のコマンドを実行してみます。

root@88e2db6c51bc:/var/lock# curl --unix-socket /run/control.unit.sock http://localhost/
{
        "listeners": {},
        "applications": {}
}

何やら空の値が帰ってきました。
NginxUnitでは、listenersapplicationsという2つの重要な概念があるようです。
指定したIPとPortにアクセスが来たら、指定したapplicationを実行する、という指定のlisteners、そして実際のアプリケーションの登録を行うapplications

API経由でJSONファイルを渡してあげることで登録できます。
まず、READMEにある通り、以下の内容のファイルを用意します。(とりあえずstart.jsonという名前にしましたが、何でもOKです)

{
     "listeners": {
         "*:8300": {
             "application": "blogs"
         }
     },
     "applications": {
         "blogs": {
             "type": "php",
              "workers": 20,
              "root": "/www/blogs/scripts",
              "index": "index.php"
         }
     }
}

そしてこれをlocalhostに投げてあげます。

root@88e2db6c51bc:~# curl -X PUT -d @/root/start.json --unix-socket /run/control.unit.sock http://localhost/                                                                                                                                                                    
{
        "success": "Reconfiguration done."
}

これで完了です。
実際に再度以下のように確認してみると、何やら値が設定されていることが確認できます。

root@88e2db6c51bc:~# curl --unix-socket /run/control.unit.sock http://localhost/
{
        "listeners": {
                "*:8300": {
                        "application": "blogs"
                }
        },

        "applications": {
                "blogs": {
                        "type": "php",
                        "workers": 20,
                        "root": "/www/blogs/scripts",
                        "index": "index.php"
                }
        }
}
root@88e2db6c51bc:~# 

PHP

では実際にコードを設置してみましょう!
先ほどのstart.jsonで、実は既にドキュメントルートを指定しています。(/www/blogs/scripts)
なので、先ずはそのディレクトリを作成します。

root@88e2db6c51bc:~# mkdir -p /www/blogs/scripts

で、後はそのディレクトリにPHPファイルを設置するだけでOKです。

echo "<?php phpinfo();?>" > /www/blogs/scripts/index.php

これで、http://localhost:8300/にアクセスすればphpinfoが表示されるはずです。

ちなみに、unitのインストールで必要なPHPのライブラリはインストールされているっぽい。楽ちん。

root@88e2db6c51bc:~# dpkg -l | grep php
ii  libphp-embed               1:7.0+35ubuntu6                       all          HTML-embedded scripting language (Embedded SAPI library) (default)
ii  libphp7.0-embed            7.0.22-0ubuntu0.16.04.1               amd64        HTML-embedded scripting language (Embedded SAPI library)
ii  php-common                 1:35ubuntu6                           all          Common files for PHP packages
ii  php7.0-common              7.0.22-0ubuntu0.16.04.1               amd64        documentation, examples and common module for PHP
root@88e2db6c51bc:~# 

感想

簡単に実行できました。
ただ、今一メリットを理解できていないのが現状です。
一つのNginx Unitさえあれば、一つのunitedプロセスで、様々な言語(現在だとPHP、Go、Pythonがサポートされている。そのうちJavaとNode.jsも予定)で実装されたサービスを動かせる、という特徴はありますが、これも今までそれぞれが持っていたアプリケーションサーバから乗り換えるほどのメリットなのか?と言われると微妙な感じです。
ただ、今回のPHPだけで考えてみると、今まではNginx(Web)とPHP-FPM(App)を別々の物として管理運用していましたが、Nginx Unitだとコレが一つに纏まる訳なので、運用面でのそういったメリットは確かにあるのかな?とぼんやりと考えています。

まぁとは言っても今回のようにPHPだけではなくて、他の言語のアプリケーションも同時にNginx Unit上で実際に運用してみて初めてメリットが見えてくるような気もしますので、Javaが正式にサポートされたタイミングなどで再度試してみて、また色々確認してみようかなと思います。