こんにちは。開発部のtorigakiです。 今回はNGINX Unitを簡単に検証した話をさせていただければと思います。
タイトルに「続」がついている理由ですが、実は2年前に社内勉強会の発表ネタ(当時の発表資料はこちら)としてNGINX Unitを検証してみたことがありまして、当時のバージョンではNode.jsとJavaが未対応だったのですが、最新バージョンでは対応済みになっていたのでブログネタとして再び検証してみようと思った次第です。
NGINX Unitとは?
要約すると以下になります。
- NGINX社製 軽量アプリケーションサーバ。
- RESTful APIやJSON経由でサービス無停止でリアルタイムに設定変更がきる。
- 1つのサーバに複数の言語の実行系や同一言語の複数バージョンの実行系を搭載できる。
インストール方法
今回は「Ubuntu 18.04.2 LTS」にインストールしてみました。
インストール方法は公式サイト通りにやってみました。
- 以下のコマンドを実行します。
# sudo curl -sL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
- 以下内容の「/etc/apt/sources.list.d/unit.list」を作成します。
deb https://packages.nginx.org/unit/ubuntu/ cosmic unit deb-src https://packages.nginx.org/unit/ubuntu/ cosmic unit
- 以下コマンドを実行します。
# apt update # apt install unit # apt install unit-dev unit-go1.10 unit-jsc8 unit-jsc11 unit-perl \ unit-php unit-python2.7 unit-python3.6 unit-python3.7 unit-ruby
起動・停止方法
以下コマンドで起動・停止できます。
# systemctl start unit # systemctl stop unit
サーバー設定
NGINX UnitはJSON形式のファイルに設定内容を記述し、curlコマンドで反映させます。
以下はPHPの設定を反映させる場合の例です。
1.以下内容のPHPファイルを配置します。
- 配置場所
/var/www/php/index.php
- index.phpの内容
<?php echo "PHP Hello, Unit!"; ?>
2.以下内容のJSONファイルを作成します。
{ "listeners": { "*:8080": { "pass": "applications/php_app" } }, "applications": { "php_app": { "type": "php", "root": "/var/www/php/" } } }
3.以下のcurlコマンドで反映させます。
curl -X PUT -d @php.json --unix-socket /var/run/control.unit.sock http://localhost/config
4.反映確認
以下のcurlコマンドで確認できます。
# curl http://localhost:8080/ PHP Hello, Unit!
ベンチマークとってみた
各言語ごとに性能差がどれくらいでるのか確認してみました。 ベンチマークにはこちらのサイトを参考にApache Benchを使用しました。
検証環境(物理PC)は以下になります。
OS:Ubuntu 18.04.2 LTS CPU:4コア メモリ:15GB NGINX Unitバージョン:1.18.0-1
Apache Benchで実行したコマンドは以下になります。
ab -n <総リクエスト数> -c <同時リクエスト数><URL> 実行したコマンド ab -n 100000 -c 100 http://localhost:8080/
ベンチマーク結果で今回比較対象にする値は以下になります。
- Requests per second(1秒で処理できるリクエスト数)(数値が高い方が好ましい)
- Time per request(1リクエストの平均処理時間)(数値が低い方が好ましい)
各言語のアプリ設定は公式サイトのサンプル通りに設定しました。
検証方法は上記abコマンドで各言語のアプリに5回アクセスし、その平均値をとってみました。
各言語ごとのアプリ内容
- Go
package main import ( "io"; "net/http"; "unit.nginx.org/go" ) func main() { http.HandleFunc("/",func (w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello, Unit!") }) unit.ListenAndServe(":8080", nil) }
- Node.js
#!/usr/bin/env node require("unit-http").createServer(function (req, res) { res.writeHead(200, {"Content-Type": "text/plain"}); res.end("Hello, Unit!") }).listen()
- Java
<%@ page language="java" contentType="text/plain" %> <%= "Hello, Unit!" %>
- Perl
my $app = sub { return [ "200", [ "Content-Type" => "text/plain" ], [ "Hello, Unit!" ], ]; };
- PHP
<?php echo "Hello, Unit!"; ?>
- Python
def application(environ, start_response): start_response("200 OK", [("Content-Type", "text/plain")]) return (b"Hello, Unit!")
- Ruby
app = Proc.new do |env| ["200", { "Content-Type" => "text/plain", }, ["Hello, Unit!"]] end run app
ベンチマーク結果
- Requests per second
Go | Node.js | Java | Perl | PHP | Python | Ruby |
---|---|---|---|---|---|---|
2009.72 | 1809.132 | 1851.91 | 1981.946 | 1998.446 | 1945.988 | 1969.374 |
- Time per request
Go | Node.js | Java | Perl | PHP | Python | Ruby |
---|---|---|---|---|---|---|
0.5024 | 0.5552 | 0.543 | 0.5056 | 0.502 | 0.5148 | 0.5106 |
今回は、「Hello, Unit!」の文字を表示するだけの簡単なアプリによる検証でしたので、このベンチマークの数値はアプリによっては変動するのではないかなと思われます。
まとめ
今回はNGINX UnitをUbuntuにインストールし、簡単なアプリを起動してベンチマークをとってみました。
本来であればphp-fpmやrailsなどとの比較検証もやるべきかと思うのですが、今回は時間がとれなかったため、また別の機会に検証できればと思っております。
弊社では引き続きエンジニア・デザイナーを募集中ですので、ご興味のある方は下からご応募いただければと思います。