NGINX Unit、2022年秋に新機能(統計エンジン!)と期待の新計画を発表

NGINX | 2022年10月27日

まず初めに、NGINX Unitチームから最新情報をお届けしてから、かなりの時間が経ってしまいました。この激動の時代は誰にとっても大きな影響をもたらし、私たちも例外ではありません。今年3月、Unitチームの創設メンバーであるValentin BartenevとMaxim Romanovは、長年にわたり多大な労力と創造性をNGINX Unitに注いだ後、新たな道へ進むことを決めました。称賛すべき功績には、正当な評価を贈りたいと思います。2人がいなければ、NGINX Unitが今日の姿になることはありませんでした。お二人の功績に心から敬意を表します。

それでも、私たちの決意は揺らいでおらず、NGINXの共同創設者Igor SysoevがNGINX Unitに託した当初の構想を実現するというコミットメントも変わりません。新たにAlejandro ColomarとAndrew Claytonの2名がチームに加わったことで開発が加速し、NGINX Unitバージョン1.25~1.28の注目すべきアップデートを数多くご紹介できるようになりました。

オブザーバビリティが実現

Unitが常に重視してきた目標の1つがオブザーバビリティです。バージョン1.28.0では、特に待望されていた機能の1つである統計エンジンの初期実装が導入されました。その出力は、新しいAPIエンドポイント「/status」で公開されます。

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

{
    "connections": {
        "accepted": 1067,
        "active": 13,
        "idle": 4,
        "closed": 1050
    },

    "requests": {
        "total": 1307
    },

    "applications": {
        "wp": {
            "processes": {
                "running": 14,
                "starting": 0,
                "idle": 4
            },

            "requests": {
                "active": 10
            }
        }
    }
}

ここにあるフィールドの大半は、その名前から内容を把握できます。connections(2行目)とrequests(9行目)はインスタンス全体のデータを提供します。一方、applicationsオブジェクト(13行目)は/config/applicationsに対応し、そのアプリケーションに固有のプロセスとリクエストを対象とします。

3~6行目には、NGINX Unitが追跡する接続の4つのカテゴリーが示されています。accepted、active、idle、closedです。プロセスのカテゴリーは、running、starting、idleです(16~18行目)。これらのカテゴリーは、接続とプロセスの内部表現を反映しています。これで、サーバーが把握しているのと同じ情報を確認できます。

簡潔すぎると感じますか?現時点で知っておくべきことは、ほぼこれだけです。もちろん、より有用なメトリクスを公開できるよう取り組んでいますが、すでにコマンドラインからこのAPIにクエリを実行して、サーバーの状況を確認できます。さらに、出力をダッシュボードに取り込むなど、お好みの方法でより見やすく表示することも可能です。ダッシュボードをお持ちでない場合もご安心ください。組み込みのダッシュボードを提供する計画もありますので、今後の展開にご注目ください。

詳細については、NGINX Unitドキュメントの「使用状況の統計」を参照してください。

変数が増え、利用できる場所も拡大

バージョン1.24以降に導入された変数は多岐にわたり、$body_bytes_sent、$header_referer、$header_user_agent、$remote_addr、$request_line、$request_uri、$status、$time_localなどがあります。

そのほとんどは比較的わかりやすいものですが、特に注目すべきものをいくつか紹介します。

  • $request_uri には、ブラウザーによるエンコードを保持したまま、リクエストされたURIのパスとクエリが含まれます
  • 同様の名前を持つ「$request_line」には、GET /docs/help.html HTTP/1.1のようなリクエスト全体が格納され、ログ記録を目的としています……
  • HTTPレスポンスステータスコードを格納する「$status」も同様です

お気づきでしょうか。ここではレスポンスについて触れています。そうです、レスポンスも対象になりました。以前のバージョンのUnitでは、変数は受信リクエストを中心に扱っていましたが、現在はレスポンスのプロパティを取得する変数も用意されています。たとえば、$statusや$body_bytes_sentです。

変数の新たな使用箇所として、まず挙げられるのが、カスタマイズ可能になったアクセスログ形式です。NGINX UnitのログエントリにJSONを使用したい場合は、単純なパス文字列を指定するだけでなく、access_logオプションにログエントリの形式も設定するオブジェクトを指定できます。


{ 
    "access_log": {
        "path": "/var/log/unit/access.log", 
        "format": "{ \"remote_addr\":\"$remote_addr\", "time\":\"$time_local\", \"request\":\"$request_line\", \"response\":\"$status\", \"header_referer\":\"$header_referer\", \"header_user_agent\":\"$header_user_agent\" }" 
    } 
}

このように、通常のログ形式にとらわれず、必要に応じて自由にカスタマイズできます。

変数のもう1つの注目すべきユースケースは、ルートのlocation値です。ルートのactionで使用します:


{ 
    "action": { 
        "return": 301, 
        "location": "https://$host$request_uri" 
    } 
 }

ここでは、$request_uriを使用して、リクエストをクエリ部分も含めて同じWebサイトにHTTPS経由で転送しています。

The chrootオプションでも、shareオプションと同様に変数がサポートされるようになりました。これは当然のことです。


{ 
    "action": { 
        "share": "/www$uri",
        "chroot": "/www/data/$host/" 
    } 
} 

NGINX Unitは動的変数にも対応しています。リクエスト引数、Cookie、ヘッダーは変数として公開されます。たとえば、クエリ文字列「Type=car&Color=red」からは、2つの引数変数「$arg_Type」と「$arg_Color」が生成されます。実行時に、これらの変数は動的な値に展開されます。存在しない変数を参照した場合、その変数は空とみなされます。

詳細については、NGINX Unitドキュメントの「変数」を参照してください。

幅広くサポートされる「X-Forwarded-*」ヘッダー

ご要望にお応えしました。バージョン1.25.0以降、NGINX Unitではリスナー向けに、X-Forwarded-*への一定の対応を含むTLS設定機能を提供してきました。今回、リスナーの設定でクライアントIPアドレスとプロトコルの置換を構成できるようになりました。


{
    "listeners": {
        "*:80": {
            "pass": "routes/my-app",
            "forwarded": {
                "client_ip": "X-Forwarded-For",
                "protocol": "X-Forwarded-Proto",
                "recursive": false,
                "source": [
                    "198.51.100.1-198.51.100.254",
                    "!198.51.100.128/26",
                    "203.0.113.195"
                ]
            }
        }
    },
    ...
}

注:この「新しい構文」により、以前の「client_ip」構文は非推奨となり、今後のリリースで削除される予定です。

詳細については、NGINX Unitドキュメントの「IP、プロトコル転送」を参照してください。

刷新された「share」オプション

NGINX Unitバージョン1.11.0では、静的コンテンツを配信するための「share」ルーティングオプションが導入されました。これは、NGINXの「root」ディレクティブに相当します。


{
    "share": "/path/to/dir/"
}

当初、shareオプションでは、いわゆるドキュメントルートディレクトリを指定していました。配信するファイルを決定する際、UnitはリクエストのURIをこのshareパスに単純に追加していました。たとえば、GETによる単純なリクエストで/some/file.htmlが指定された場合、Unitは/path/to/dir/some/file.htmlを配信していました。しかし、ファイルパスをより細かく制御する必要がある境界的なケースにたびたび直面したため、仕様を拡張することにしました。バージョン1.26.0以降、shareオプションでは、ドキュメントルートだけでなく、共有ファイルへの完全なパスを指定します。

特定のファイルを配信する場合は、次のようにします。


{
    "share": "/path/to/a/file.html"
}

パス内で変数を使用する場合も問題ありません:


{
    "share": "/www/data/$host/app.html"
}

では、NGINXや以前のバージョンのUnitで使い慣れた動作を再現するには、どうすればよいのでしょうか。数段落前に廃止されたと説明した、あのドキュメントルートのことです。解決策があります。

これで、設定を次のように書き換えられます。


{
    "share": "/www/data/"
}

次のように、リクエストされたURIをパスに明示的に追加します。


{
    "share": "/www/data/$uri"
}

最後に、shareディレクティブでパスの配列を指定できるようになりました。ファイルが見つかるまで、各パスを順番に試行します。


{
    "share": [
        "/www/$host$uri",
        "/www/static$uri",
        "/www/app.html"
    ]
}

ファイルが見つからない場合、ルーティングはfallbackアクションに移ります。fallbackがない場合は、404 (Not Found)ステータスコードが返されます。

詳細については、NGINX Unitドキュメントの「静的ファイル」を参照してください。

計画:njs、URI Rewrite、Action Chaining、OpenAPI

この記事をお読みいただいている今も、次期リリースに向けた作業を進めています。今後の計画を少しご紹介します。

まず、NGINX UnitをNGINX JavaScriptモジュール(njs)と統合します。njsも、NGINXで活発に開発が進められている中核プロジェクトの1つです。つまり、NGINX UnitからJavaScriptモジュールを呼び出せるようになります。次の例をご覧ください。


var hellonjs = {}

hellonjs.hello = function(vars) {
    if ('unitvar' in vars) {
        return vars.unitvar;

    } else {
        return 'default';
    }
}

export default hellonjs

NGINX Unitにモジュールをインポートすると、設定を使って次のような便利なことができるようになります。


{
    "match": {
        "uri": "~(?.*)" }, "action": { "share": "`/www/html${hellonjs.hello(vars)}`" } }

また、広く利用されているNGINXの「rewrite」ディレクティブに似た機能の導入も目指しています。


{
    "match": {
        "uri": "/app/old_path"
     },
     
    "action": {
        "rewrite": "/app/new_path",
        "pass": "routes"
    }
}

しかし、私たちの計画はこれだけではありません。NGINX Unitのルーティングをアプリ自体の出力に連携させるのはどうでしょうか(いわゆる「actionチェーン」)?


{
    "action": [
        {
            "pass": "applications/auth_check"
        },
        {
            "pass": "applications/my_app"
        }
    ]
}

ここでは、auth_checkアプリが受信リクエストを認証し、その結果を示すステータスコードを返します。認証に成功すると、200 OKが返され、リクエストはmy_appに渡されます。

一方、現在、OpenAPI仕様の策定にも取り組んでいます。これは、NGINX UnitのAPIとその正確な機能を明確に定義するためのものです。非常に大規模な取り組みですので、ぜひ応援してください。

さらに詳しく知りたい方は、今後の計画を詳細にまとめたロードマップをご覧ください。インタラクティブ形式ですので、皆さまからのご意見をお待ちしています。


共有

関連するブログ記事

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
NGINX | 2024/01/18

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する

OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
NGINX | 2023/05/31

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正

Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
NGINX | 2023/02/09

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法

Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINX | 2022/05/24

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング

NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
NGINX | 2018/08/17

SELinuxでNGINXおよびNGINX Plusを使用する

Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。

NGINX PlusによるAWS Auto Scalingグループの負荷分散
NGINX | 2017/03/06

NGINX PlusによるAWS Auto Scalingグループの負荷分散

新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります