LuaRocksとOPMを通じてOpenRestyのサードパーティパッケージを管理する方法

API7.ai

September 17, 2022

OpenResty (NGINX + Lua)

前回の投稿では、いくつかの公式OpenRestyプロジェクトの概要を紹介しました。しかし、OpenRestyを本番環境で使用する場合、OpenRestyパッケージに付属するこれらのライブラリだけでは不十分です。例えば、HTTPリクエストを送信するためのlua-restyライブラリがなく、Kafkaとやり取りする方法もありません。

では、どうすればよいでしょうか?

OpenRestyはNGINXのフォークではなく、標準ライブラリをいくつか追加してNGINXを再パッケージしたものでもありません。代わりに、NGINXを基盤のネットワークライブラリとして使用しているだけです。

NGINXを使用する場合、カスタムHTTPリクエストを開始する方法やKafkaとやり取りする方法について考えることはありません。そして、OpenRestyの世界では、cosocketのおかげで、開発者はPythonやPHPなどの開発言語と同じように、lua-resty-httplua-resty-kafkaを迅速に作成してこれらのニーズに対応できます。

もう一つアドバイスをすると、上記の問題を解決するためにLuaの世界のライブラリを使用すべきではありません。代わりに、cosocketのlua-resty-*ライブラリを使用してください。Luaの世界のライブラリはブロッキングを引き起こす可能性があり、それによって高性能なサービスが数桁も低下する可能性があります。これはOpenResty初心者によくある間違いで、簡単には気づきません。

では、これらの非ブロッキングなlua-resty-*ライブラリをどのように見つければよいでしょうか?次に、以下の方法を紹介します。

OPM

OPM(OpenResty Package Manager)は、OpenRestyに付属するパッケージマネージャーで、OpenRestyをインストールした後に使用できます。opm search httpコマンドを使用して、HTTPリクエストを送信するライブラリを探してみましょう。

初回のクエリは遅いかもしれませんが、通常数秒かかります。opm.openresty.orgはPostgreSQLデータベースからクエリを行い、結果をしばらくキャッシュします。

openresty/lua-resty-upload                            Streaming reader and parser for HTTP file uploading based on ngx_lua cosocket

この結果を見たとき、あなたは疑問に思うかもしれません:このlua-resty-uploadパッケージはHTTP送信と何の関係があるのか?

実は、OPMが検索する際、パッケージ名とパッケージのプロファイルの両方を後者のキーワードで検索しています。これが、上記の検索が数秒かかる理由です。PostgreSQL内の文字列を全文検索しています。

しかし、とにかくこの返答は親切ではありません。キーワードを修正して再度検索してみましょう。

$ opm search lua-resty-http

ledgetech/lua-resty-http                          Lua HTTP client cosocket driver for OpenResty/ngx_lua
pintsized/lua-resty-http                          Lua HTTP client cosocket driver for OpenResty/ngx_lua
agentzh/lua-resty-http                            Lua HTTP client cosocket driver for OpenResty/ngx_lua

OpenRestyの世界では、cosocketを使用してパッケージを実装する場合、lua-restyプレフィックスを使用する必要があります。これは不文律です。

検索結果を見ると、OPMは貢献者のGitHubリポジトリアドレスをパッケージ名として使用しています。つまり、GitHub ID / リポジトリ名です。3つのlua-resty-httpサードパーティライブラリが返されました。どれを選ぶべきでしょうか?

パッケージを選ぶ前に、そのスター数と最終更新日を見てみましょう:スターは十数個しかなく、最新の更新は2016年です。これは放棄されたプロジェクトです。さらに深く見ると、pintsized/lua-resty-httpledgetech/lua-resty-httpは同じリポジトリを指しています。したがって、どちらを選んでも同じです。

また、OPMのウェブサイトは比較的シンプルで、パッケージのダウンロード数やこのパッケージの依存関係を提供していません。そのため、どのlua-restyライブラリを使用するのが適切かを理解するためにより多くの時間を費やす必要がありますが、これは本来メンテナの仕事であるべきです。

LuaRocks

LuaRocksは、OpenRestyの世界のもう一つのパッケージマネージャーで、OPMよりも前に誕生しました。OPMがOpenResty関連のパッケージのみを含むのに対し、LuaRocksにはLuaの世界のライブラリも含まれています。例えば、LuaRocksのLuaSQL-MySQLは、Luaの世界でMySQLに接続するためのパッケージで、OpenRestyでは使用できません。

引き続きHTTPライブラリを例として、LuaRocksを使用して探してみましょう。

$ luarocks search http

ご覧のとおり、多くのパッケージが返されます。

キーワードを再度変更してみましょう。

$ luarocks search lua-resty-http

今回は1つのパッケージのみが返されました。LuaRocksのウェブサイトにアクセスして、このパッケージの詳細を見ることができます。以下はウェブサイトページのスクリーンショットです。

LuaRocks Package Details

上記のスクリーンショットには、作者、ライセンス、GitHub URL、ダウンロード数、機能の概要、バージョン履歴、依存関係などが含まれています。OPMとは異なり、LuaRocksはGitHubのユーザー情報を直接使用せず、開発者がLuaRocksに別途登録する必要があります。

オープンソースのAPIゲートウェイプロジェクトであるApache APISIXは、パッケージ管理にLuaRocksを使用しています。APISIXのパッケージ管理設定がどのように記述されているかを簡単に見てみましょう。

APISIXの最新バージョンは2.15で、Apache APISIXプロジェクトの下にapisix-2.15.0-0.rockspecファイルを見つけることができます。

package = "apisix"
version = "2.15.0-0"
supported_platforms = {"linux", "macosx"}

source = {
    url = "git://github.com/apache/apisix",
    branch = "2.15.0",
}

description = {
    summary = "Apache APISIX is a cloud-native microservices API gateway, delivering the ultimate performance, security, open source and scalable platform for all your APIs and microservices.",
    homepage = "https://github.com/apache/apisix",
    license = "Apache License 2.0",
}

dependencies = {
    "lua-resty-ctxdump = 0.1-0",
    "lua-resty-dns-client = 6.0.2",
    "lua-resty-template = 2.0",
    "lua-resty-etcd = 1.8.2",
    "api7-lua-resty-http = 0.2.0",
    "lua-resty-balancer = 0.04",
    "lua-resty-ngxvar = 0.5.2",
    "lua-resty-jit-uuid = 0.0.7",
    "lua-resty-healthcheck-api7 = 2.2.0",
    "api7-lua-resty-jwt = 0.2.4",
    "lua-resty-hmac-ffi = 0.05",
    "lua-resty-cookie = 0.1.0",
    "lua-resty-session = 3.10",
    "opentracing-openresty = 0.1",
    "lua-resty-radixtree = 2.8.2",
    "lua-protobuf = 0.3.4",
    "lua-resty-openidc = 1.7.5",
    "luafilesystem = 1.7.0-2",
    "api7-lua-tinyyaml = 0.4.2",
    "nginx-lua-prometheus = 0.20220527",
    "jsonschema = 0.9.8",
    "lua-resty-ipmatcher = 0.6.1",
    "lua-resty-kafka = 0.20-0",
    "lua-resty-logger-socket = 2.0.1-0",
    "skywalking-nginx-lua = 0.6.0",
    "base64 = 1.5-2",
    "binaryheap = 0.4",
    "api7-dkjson = 0.1.1",
    "resty-redis-cluster = 1.02-4",
    "lua-resty-expr = 1.3.1",
    "graphql = 0.0.2",
    "argparse = 0.7.1-1",
    "luasocket = 3.0rc1-2",
    "luasec = 0.9-1",
    "lua-resty-consul = 0.3-2",
    "penlight = 1.9.2-1",
    "ext-plugin-proto = 0.5.0",
    "casbin = 1.41.1",
    "api7-snowflake = 2.0-1",
    "inspect == 3.1.1",
    "lualdap = 1.2.6-1",
    "lua-resty-rocketmq = 0.3.0-0",
    "opentelemetry-lua = 0.1-3",
    "net-url = 0.9-1",
    "xml2lua = 1.5-2",
    "nanoid = 0.1-1",
    "lua-resty-mediador = 0.1.2-1"
}

build = {
    type = "make",
    build_variables = {
        CFLAGS="$(CFLAGS)",
        LIBFLAG="$(LIBFLAG)",
        LUA_LIBDIR="$(LUA_LIBDIR)",
        LUA_BINDIR="$(LUA_BINDIR)",
        LUA_INCDIR="$(LUA_INCDIR)",
        LUA="$(LUA)",
        OPENSSL_INCDIR="$(OPENSSL_INCDIR)",
        OPENSSL_LIBDIR="$(OPENSSL_LIBDIR)",
    },
    install_variables = {
        ENV_INST_PREFIX="$(PREFIX)",
        ENV_INST_BINDIR="$(BINDIR)",
        ENV_INST_LIBDIR="$(LIBDIR)",
        ENV_INST_LUADIR="$(LUADIR)",
        ENV_INST_CONFDIR="$(CONFDIR)",
    },
}

ファイルからわかるように、依存関係にはlua-resty-*ライブラリと純粋なLuaの世界のライブラリが混在しており、OPMでは完全にインストールできません。設定を記述した後、LuaRocksのアップロードコマンドを使用してこの設定をアップロードし、ユーザーはLuaRocksを使用してAPISIXをダウンロードしてインストールできます。

LuaRocksはこれをサポートしています。.rockspecファイルにCソースコードのパスと名前を指定すると、LuaRocksがローカルでコンパイルしてくれます。OPMはまだこの機能をサポートしていません。

awesome-resty

awesome-restyプロジェクトは、OpenRestyで利用可能なほぼすべてのパッケージをカテゴリ別に整理して管理しています。適切なサードパーティパッケージがあるかどうかわからない場合、ここに行くのが最適です。

HTTPライブラリを例として、awesome-restyでは自然にnetworkingカテゴリに属します。

lua-resty-http by @pintsized — Lua HTTP client cosocket driver for OpenResty / ngx_lua
lua-resty-http by @liseen — Lua http client driver for the ngx_lua based on the cosocket API
lua-resty-http by @DorianGray — Lua HTTP client driver for ngx_lua based on the cosocket API
lua-resty-http-simple — Simple Lua HTTP client driver for ngx_lua
lua-resty-httpipe — Lua HTTP client cosocket driver for OpenResty / ngx_lua
lua-resty-httpclient — Nonblocking Lua HTTP Client library for aLiLua & ngx_lua
lua-httpcli-resty — Lua HTTP client module for OpenResty
lua-resty-requests — Yet Another HTTP Library for OpenResty

lua-resty-httpの8つのサードパーティライブラリがあることがわかります。以前の結果と比較すると、OPMでは2つしか見つからず、LuaRocksでは1つしか見つかりませんでした。しかし、選択が難しい場合は、最初のものを使用してください。これはLuaRocksのものと同じです。

実験を好むエンジニアには、最後のライブラリ:lua-resty-requestsをお勧めします。これはPythonの有名なRequestsと同じインターフェーススタイルを持つ、より人間に優しいHTTPアクセスライブラリです。私のようにPythonが好きな方なら、lua-resty-requestsを気に入るでしょう。これはOpenRestyコミュニティで活躍しているtokersによって作成されているため、自信を持って使用できます。

まとめ

オープンソースプロジェクトが繁栄するためには、ハードコアな技術、良いドキュメント、完全なテストだけでなく、より多くの開発者や企業を結集するエコシステムが必要です。Apache Wayが言うように:コードよりもコミュニティが重要です。

OpenRestyには体系的な学習教材がなく、公式のコードガイドもありません。多くの最適化ポイントがオープンソースプロジェクトに記述されていますが、ほとんどの開発者は何を言っているのかはわかっても、なぜそうなのかは理解していません。これがこのEbookの目的です。これを学んだ後、より効率的なOpenRestyコードを書くことができ、Apache APISIXなどのOpenResty関連のオープンソースプロジェクトに効率的に参加できることを願っています。

OpenRestyのエコシステムについてどう思いますか?コメントを残して、話し合いましょう。また、この記事を共有するのも歓迎です。