とあるインフラエンジニアの日常

インフラ、ネットワークに囲まれた日常をつらつらと書いていきます。時々旨い酒

nginx unitを試してみたら面白かった件

みなさんこんにちは

前回はprometheusを試していて、まだ全然postしおわってないのですが、こんなニュースが入ってきたので飛びついてしまいました。

www.publickey1.jp

nginx unitとは?

nginxのソフトウェア開発チームが実装した、Webアプリケーション・サーバーで、下記のような特徴があります。

  1. たくさんの言語に対応したWebアプリケーション・サーバー(php, python, go, java, node.js)
  2. バージョンアップのシームレスな実行
  3. REST APIを経由したconfig

個人的に特に気になったのが3番。jsonREST APIで設定を投入できるというのはdevelperでも設定の敷居が下がりそうだなーって思いました。 公式のドキュメントを読む限りでも、nginxのバックエンドに配置する用途を想定しているようです。

インストール

今回は手間を省くために、公式サイトにある通りリポジトリを登録してyumでインストールしました。 http://unit.nginx.org/docs-installation.html#precompiled-packages

実際に使ってみた with python

flaskで作成したpythonのプログラムを動かしてみます。

設定の作成

unitにはApplicationとListenerという2つの重要な概念があるので、それぞれ設定を進めていきます。

  • Applicationはアプリケーションごとに、使用する言語やドキュメントルートなどの設定を定義するブロックです。
  • Listenerはどのようなポートでどのアプリケーションを待ち受けるかを定義します。

最終的に完成した設定はこちらです。

start.json

{
        "listeners": {
                "*:8300": {
                        "application": "my_python"
                }
        },

        "applications": {
                "my_python": {
                        "type": "python",
                        "workers": 10,
                        "path": "/var/www/mypython",
                        "module": "wsgi"
                }
        }
}

この設定内容は下記と同じ意味です。

  • /var/www/myphthon/wsgi.pyに作成されたWSGIアプリケーションmy_pythonを定義
  • アプリケーションの待受ポート8300にpy_pythonを割り当てる

設定の反映(APIで送信)

設定の作成が完了したので、実際に投入してみたいと思います。 最初に、APIを送るためにsystemctl start unitdでunitのサービスをUPしておきます。

次に、下記コマンドで設定ファイルをpost.

curl -X PUT -d @start.json --unix-socket /run/control.unit.sock http://localhost/

設定が反映されているか、getで確認。

curl --unix-socket /run/control.unit.sock http://localhost/

下記のように設定ファイルが表示されたら成功しています。

[root@fluentd-with-apache ~]# curl --unix-socket /run/control.unit.sock http://localhost/
{
        "listeners": {
                "*:8300": {
                        "application": "my_python"
                }
        },

        "applications": {
                "my_python": {
                        "type": "python",
                        "module": "wsgi",
                        "workers": 10,
                        "path": "/var/www/mypython"
                }
        }
}

動かしてみる

最後に、適当なWSGIアプリケーションを作成して、実際にその結果を確認してみましょう。今回は下記のようなかんたんなプログラムにしました。 /var/www/mypython/wsgi.py

#!/usr/bin/env python

from flask import Flask

application = Flask(__name__)

@application.route("/")
def index():
    return "nginx with python"

これで、実際にアクセスしてみるとこんな感じで動くことがわかりました。

http://localhost:8300/ f:id:kurokiyokiyo:20170910215443p:plain

実際に使ってみた with php

基本はPython(wsgi)と同じ。下記のようにPHP用の設定を入れてあげれば動作する

{
        "listeners": {
                "*:8300": {
                        "application": "my_python"
                },
                "*:8400": {
                        "application": "my_php"
                }
        },

        "applications": {
                "my_python": {
                        "type": "python",
                        "module": "wsgi",
                        "workers": 10,
                        "path": "/var/www/mypython",
                },
                "my_php": {
                        "type": "php",
                        "workers": 10,
                        "root": "/var/www/html",
                }
        }
}

使ってみて気になったところ(memo)

今回使ってみた結果、非常にわかりやすくおもしろかったです。 下記の通り色々発展途上なところがありましたが、設定で回避できるところもあるかもしれないので調べて行きたいと思います。

  • サービスをrestartするたびに設定が揮発するので、serviceをstartする際に設定をpostする必要がある
  • wsgiが格納されている変数名画applicationじゃないと動作しない
    • 変数名appだとtimeoutになってしまった
    • 変更オプションとかあるか調べようと思う
  • pyenvが使えない(←超重要
    • システムのpythonを触って壊したりしたくない。。。。。。(systemのpythonでpipとかキケン)