OpenResty XRay がどのようにしてアプリケーションの問題特定と効率化を支援するかをご覧ください。

詳細はこちら LIVE DEMO

このチュートリアルでは、Lua モジュールを LuaJIT バイトコードに事前コンパイルする方法を説明します。これにより、OpenResty アプリケーションの起動時間を短縮することができます。

export PATH=/usr/local/openresty/bin:$PATH
cd ~
mkdir -p precomp
cd precomp/

截图 1

ここでは、大規模な Lua モジュールファイル pkg-stap.lua を使用します。これは、当社の opslang コンパイラによって生成されたものです。

cp ~/git/opslang/pkg-stap.lua ./
ls -lh *.lua

截图 2

この Lua モジュールのサイズが 1.6MB であることがわかります。

resty ツールを使用してこの Lua モジュールをロードしてみましょう。

time resty -I. -e 'require "pkg-stap"'

截图 4

合計で 23 ミリ秒かかります。

空の Lua プログラムを実行する際の基本的なオーバーヘッドを確認してみましょう。

time resty -e ''

截图 6

約 11 ミリ秒です。つまり、モジュールのロード自体に約 12 ミリ秒かかっていることになります。

Lua モジュールを LuaJIT バイトコードに事前コンパイルしてみましょう。

time /usr/local/openresty/luajit/bin/luajit -bg pkg-stap.lua pkg-stap.ljbc

截图 8

ここでは、OpenResty の luajit プログラムを使用します。

これにより、拡張子が .ljbc の LuaJIT バイトコードファイルが生成されます。

ls -lh *.ljbc

截图 10

興味深いことに、バイトコードファイルのサイズが 50% 以上小さくなっていることがわかります!

次に、resty を使用して再度ロードしてみましょう。

time resty -I. -e 'require "pkg-stap"'

截图 12

合計でわずか 13 ミリ秒です!

今や、ほぼ空の Lua プログラムをロードするのと同じくらいの速さです!わずか 2 ミリ秒の差しかありません。

time resty -e ''

截图 14

モジュールをロードする際、resty ツールは常に .lua ファイルの前に .ljbc ファイルのロードを試みます。

OpenResty サーバーでこれを機能させる方法を見てみましょう。

mkdir conf logs lua

截图 16

Lua モジュールファイルを lua/ サブディレクトリにコピーします。

mv *.lua *.ljbc lua/
tree .

截图 17

簡単な nginx 設定ファイル conf/nginx.conf を作成します。以下のように編集します。

  1. 単一の nginx ワーカープロセスを有効にします。
  2. ワーカープロセスごとに 1024 の接続を使用します。
  3. lua_package_path ディレクティブでは、.lua ファイルの前に .ljbc ファイルを試すことが重要です。.ljbc ファイルのみを残して試すこともできます。
  4. init_by_lua_block では、モジュールを事前にロードしています。これにより、モジュールのロードに失敗した場合、サーバー起動時に検出できます。また、これにより最初のリクエストが高速化され、COW 最適化によりメモリ使用量も削減されます。
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    lua_package_path "$prefix/lua/?.ljbc;$prefix/lua/?.lua;;";

    init_by_lua_block {
        require "pkg-stap"
    }

    server {
        listen 8080;
        location / { return 200 "ok\n"; }
    }
}

ディレクトリツリーを確認します。

tree .

截图 26

問題ありません!

-t オプションを使用してサーバー設定をテストしてみましょう。

time openresty -p $PWD/ -t

サーバーを起動します。

time openresty -p $PWD/

截图 29

約 7 ミリ秒かかりました。

LuaJIT のバイトコードファイルを削除してみましょう。

rm lua/*.ljbc

截图 31

サーバーを停止します。

kill -QUIT `cat logs/nginx.pid`

截图 32

サーバーを再度起動します。

time openresty -p $PWD/

截图 33

今回は 17 ミリ秒かかりました!Lua ソースファイルを読み込むことで、10 ミリ秒遅くなったことがわかります。

最後に、Lua ソースファイルも削除してみましょう。

rm lua/*.lua

截图 35

サーバーを停止し、再起動します。

time openresty -p $PWD/

截图 36

今回は、両方のバージョンのモジュールが見つからないため、予想通りのエラーが発生しました。

小さな Lua モジュールファイルの場合、そのソースコードを読み込むのは既にかなり高速です。

echo 'local _M = {} function _M.foo() end return _M' > a.lua
ls -l a.lua
time resty -I. -e 'require "a"'

截图 38

小さな Lua モジュールファイルをプリコンパイルしても、大きな効果は得られません。

time /usr/local/openresty/luajit/bin/luajit -bg a.lua a.ljbc
time resty -I. -e 'require "a"'

截图 39

確かに大きな違いはありません。しかし、多数の小さなモジュールを読み込む必要がある場合、節約される時間はすぐに積み重なっていきます。

著者について

章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。

章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay動的トレーシング技術を利用した非侵襲的な障害分析および排除ツール)と OpenResty Edge(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJITGDBSystemTapLLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。

翻訳

英文版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!