OpenRestyとNGINXの違いは何ですか?

API7.ai

September 9, 2022

OpenResty (NGINX + Lua)

OpenRestyの利点は明らかです。詳細を学ぶ前に、OpenRestyの開発プロセスを簡単に振り返りましょう。これにより、以下の内容をよりよく理解できるようになります。

OpenRestyの開発プロセス

OpenRestyは他の開発言語のようにゼロから構築されたものではなく、成熟したオープンソースコンポーネントであるNGINXLuaJITを基盤としています。OpenRestyは2007年に誕生しましたが、最初のバージョンではLuaではなくPerlが採用されました。これは作者の技術的嗜好と大きく関係しています。

しかし、Perlの性能は要求を満たすには程遠く、第二バージョンではPerlがLuaに置き換えられました。ただし、OpenRestyの公式プロジェクトでは、Perlは依然として重要な役割を果たしています。OpenRestyのエコシステムプロジェクトはPerlで構築されており、テストフレームワーク、Linter、CLIなどが含まれます。これらについては後ほど順を追って紹介します。

OpenRestyの高性能と動的な利点はCDNビジネスのニーズに非常に適しているため、OpenRestyはすぐにCDNの技術標準となりました。さらに、豊富なlua-resty-*ライブラリを通じて、OpenRestyはNGINXの影から徐々に脱却し、独自のエコシステムを形成し、APIゲートウェイやソフトWAFなどの分野で広く使用されるようになりました。

私はよく、OpenRestyは広く使われている技術だが、人気のある技術ではないと言います。これは矛盾しているように聞こえますが、どういう意味でしょうか?

広く使われている理由は、OpenRestyが現在世界で5番目に広く使われているWebサーバーであるためです。

人気がない理由は、OpenRestyを使ってビジネスシステムを構築する割合が高くないためです。ほとんどのユーザーはOpenRestyを入口トラフィックの処理に使用し、ビジネスに深く関わることはありません。そのため、OpenRestyの使用は表面的なものであり、現在のニーズを満たすのに十分です。これはもちろん、OpenRestyがJavaやPythonのような成熟したWebフレームワークやエコシステムを持っていないこととも関係しています。

これまで多くのことを述べてきましたが、次に、OpenRestyというオープンソースプロジェクトが称賛に値し、学ぶべき点をいくつか紹介します。

OpenRestyのハイライト

詳細なドキュメントとテストケース

はい、ドキュメントとテストは、オープンソースプロジェクトが信頼できるかどうかを判断する重要な指標であり、コード品質や性能よりも優先されることがあります。

OpenRestyのドキュメントは非常に詳細で、作者はドキュメントに注意すべき点をすべて記載しています。ほとんどの場合、ドキュメントを注意深く読むだけで、問題を解決することができ、Google検索やソースコードの追跡をする必要はありません。便利なことに、OpenRestyにはコマンドラインツールrestydocが付属しており、シェルを通じてドキュメントを閲覧し、コーディングプロセスを中断することなく問題を解決するのに役立ちます。

ただし、ドキュメントには利用可能なコードスニペットが1つか2つしかなく、完全で複雑な例はありません。そのような例はどこで見つけられるでしょうか?

OpenRestyの場合、自然と/tディレクトリが該当します。このディレクトリにはすべてのテストケースが含まれており、各テストケースには完全なNGINX設定とLuaコード、およびテスト入力と期待される出力データが含まれています。ただし、OpenRestyのテストフレームワークは他のアサーションスタイルのテストフレームワークとは全く異なります。これについては後ほど特別な章で紹介します。

同期非ブロッキング

コルーチンは、近年多くのスクリプト言語が性能向上のために追加した新機能です。しかし、それらは完璧に実装されているわけではなく、一部はシンタックスシュガーであり、一部は明示的なキーワード宣言が必要です。

OpenRestyは初日からコルーチンをサポートしており、同期非ブロッキングのプログラミングモデルを実装しています。これは重要です。なぜなら、プログラマーも人間であり、コードは人間の思考習慣に合わせるべきだからです。明示的なコールバックや非同期キーワードは思考を中断し、デバッグを困難にします。

では、同期非ブロッキングとは何でしょうか?まず同期について話しましょう。これは非常に簡単で、コードに従って順次実行することです。例えば、以下の擬似コードを見てください:

local res, err  = query-mysql(sql)
local value, err = query-redis(key)

同じリクエスト内で、MySQLのクエリ結果が返されるのを待ってからRedisをクエリする必要がある場合、それは同期です。MySQLの返りを待たずにRedisをクエリできる場合、それは非同期です。OpenRestyの場合、ほとんどが同期操作です。ngx.timerのようなバックグラウンドタイマーに関連するAPIのみが非同期操作です。

非ブロッキングについては、非同期と混同されやすい概念です。ここで言うブロッキングとは、オペレーティングシステムのスレッドをブロックすることを意味します。上記の例を続けて見てみましょう。MySQLのクエリに1sかかると仮定します。この1sの間に、オペレーティングシステムのリソース(CPU)がアイドル状態で愚かに返りを待っている場合、それはブロッキングです。CPUが他の接続リクエストを処理する機会を得る場合、それは非ブロッキングです。非ブロッキングは、C10KやC100Kのような高い並行性を実現する鍵でもあります。

同期非ブロッキングの概念は重要です。しかし、私の意見では、この概念は類推で理解すべきではありません。不適切な類推は、むしろ混乱を招く可能性が高いからです。

OpenRestyでは、上記の擬似コードは明示的なキーワードなしで直接同期非ブロッキングを実現できます。ここでも、開発者が使いやすくすることがOpenRestyのコンセプトの一つであることが再び示されています。

動的性

OpenRestyの大きな利点の一つであり、まだ十分に活用されていないのが、その動的性です。

従来のWebサーバー、例えばNGINXは、ランタイムの動作を制御するAPIを提供していないため、変更が発生した場合、ディスク上の設定ファイルを修正してリロードする必要があります。そのため、頻繁に変更が必要なマイクロサービスでは、NGINXは何度も試みましたが、何も改善されませんでした。そして、Envoyの突然の登場と、xDSの動的制御APIにより、NGINXに対する次元攻撃の大きな脅威が生まれました。

NGINXやEnvoyとは異なり、OpenRestyはスクリプト言語Luaによって制御され、動的性はLuaの自然な利点です。例えば、OpenRestyのlua-nginx-moduleモジュールで提供されるLua APIを通じて、ルート、アップストリーム、SSL証明書、リクエスト、レスポンスなどを動的に制御できます。さらに、OpenRestyを再起動することなく、ビジネスの処理ロジックを変更することも可能です。これはOpenRestyが提供するLua APIに限定されません。

上記の動的性について理解を深めるために、良い類推があります。Webサーバーを高速道路を走る車と考えてください。NGINXはタイヤを交換したり、塗装色を変更するために停止する必要があります。Envoyは走行中にタイヤや色を変更できます。そしてOpenRestyは、前者の能力に加えて、駐車せずにSUVに変身することもできます。

この魔法の能力を習得した後、OpenRestyの能力範囲と想像力は、Serverlessやエッジコンピューティングなどの他の分野にまで拡大しました。

何を学ぶべきか?

OpenRestyの重要な機能についてこれまで多くのことを述べてきましたが、私たちは何を学ぶべきでしょうか?私は、眉毛やひげを掴むのではなく、主線に焦点を当てることを好みます。これにより、明確な文脈を持つ知識体系を構築できます。

どんなに包括的なコースでも、すべての問題をカバーすることは不可能であり、オンラインでのすべてのバグや例外を直接解決するのに役立つことはできないことを知っておく必要があります。

OpenRestyの学習に戻ると、私の意見では、OpenRestyをよく学ぶためには、以下の8つの重要なポイントを理解する必要があります:

  • 同期非ブロッキングプログラミングモデル
  • 異なるRequest/Responseフェーズの役割
  • LuaJITとLuaの違い
  • OpenResty APIと周辺ライブラリ
  • コルーチンとcosocket
  • ユニットテストフレームワークと性能テストツール
  • フレームグラフと周辺ツールチェーン
  • 性能最適化

これらのポイントは私たちの学習において重要であり、各章で個別に議論します。ただし、学習の過程で、一つのケースから類推し、興味や背景に応じていくつかの章を深く読むことを望みます。

もしあなたがOpenRestyの初心者であれば、コースの進捗に従って、環境にOpenRestyをインストールし、サンプルコードを実行して修正することができます。覚えておいてください、あなたの焦点はOpenRestyの全体像を構築することであり、単一の知識点に固執することではありません。もちろん、質問があれば、ライブチャットでお気軽にお問い合わせください。

もしあなたがプロジェクトでOpenRestyを使用しているなら、それは素晴らしいことです!ただし、LuaJITと性能最適化の章を読むとき、より多くの共感と実用的な応用を見出し、プロジェクト内での最適化前後の性能向上を確認できるでしょう。

さらに、OpenRestyや周辺ライブラリにコードを貢献したい場合、最大の障壁はOpenRestyの原理やNGINX Cモジュールの書き方を理解することではなく、テストケースとコード規約です。私はあまりにも多くのOpenResty貢献者(私を含む)がPR上でテストケースやコードスタイルを繰り返し修正しているのを見てきました。そして、あまりにも多くの不文律があります。そのため、コースのコード規約とユニットテストのセクションはあなたのためのものです。

そして、もしあなたがQAエンジニアであれば、OpenRestyを使用していなくても、OpenRestyのテストフレームワークと性能分析ツールセットは多くのインスピレーションを与えてくれるでしょう。結局のところ、OpenRestyのテストへの投資と蓄積は非常に深いものです。

さらに読む