预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
Posted 糖果的实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度相关的知识,希望对你有一定的参考价值。
本教程演示了如何将 Lua 模块预编译成 LuaJIT 字节码。这可以帮助减少 OpenResty 应用程序的启动时间。
export PATH=/usr/local/openresty/bin:$PATH
cd ~
mkdir -p precomp
cd precomp/
这里我们将使用一个大的Lua模块文件pkg-stap.lua
。它是由我们的 opslang 编译器生成的。
cp ~/git/opslang/pkg-stap.lua ./
ls -lh *.lua
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/c5a3629748fb48ddb7dd32248cdf2bb2.jpg)
我们可以看到,这个Lua模块是 1.6MB。
让我们尝试用resty
工具加载这个 Lua 模块。
time resty -I. -e 'require "pkg-stap"'
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/2f27d0a407c949d8986f4f8f11039ec2.jpg)
一共需要 23毫秒。
让我们检查一下运行一个空的 Lua 程序的原始开销。
time resty -e ''
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/a3469bd14751472fb8055b9140aae289.jpg)
大约是 11毫秒。所以加载模块本身大约需要 12毫秒。
让我们尝试将 Lua 模块预编译成 LuaJIT 字节码。
time /usr/local/openresty/luajit/bin/luajit -bg pkg-stap.lua pkg-stap.ljbc
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/6d1fe3db9ed04ab0991a2c77dc7d6c42.jpg)
这里我们使用 OpenResty 的luajit
程序。
它生成一个 LuaJIT 字节码文件,文件扩展名为.ljbc
。
ls -lh *.ljbc
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/85819cc5ac6a4b62bcc85806aa419a57.jpg)
看到字节码文件也小了 50% 以上,很有意思!
然后再尝试用resty
加载。
time resty -I. -e 'require "pkg-stap"'
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/fc190e94ed244ab487a6bebade1d9b48.jpg)
总共只有 13毫秒!
现在几乎就像加载一个空的 Lua 程序一样!只多了 2毫秒。
time resty -e ''
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/31f5742808534094803bfd20226c432f.jpg)
当加载一个模块时,"resty" 工具总是试图在 ".lua" 文件之前加载一个 ".ljbc" 文件。
让我们看看如何让它在 OpenResty 服务器上工作。
mkdir conf logs lua
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/f6f6f0a878254955b69cad2a543e57db.jpg)
将我们的 Lua 模块文件复制到lua/
子目录下。
mv *.lua *.ljbc lua/
tree .
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/107311ef65e041379b0d396ad4ca9ec6.jpg)
写一个简单的 nginx 配置文件,conf/nginx.conf
。我们做如下编辑。
-
启用单个 nginx 工作进程。 -
使用 1024 个每工作进程的连接。 -
在 lua_package_path
指令中,重要的是要在.lua
文件之前尝试.ljbc
文件。你也可以尝试只保留.ljbc
文件来确定。 -
在 "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
"; }
}
}
检查目录树。
tree .
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/8d41eb8b514a480aa0c693f450b4776b.jpg)
看起来不错!
尝试使用-t
选项测试服务器配置。
time openresty -p $PWD/ -t
启动它。
time openresty -p $PWD/
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/adaf6d41a03a4b77ba373e425bb3264d.jpg)
约 7毫秒。
尝试删除 LuaJIT 字节码文件。
rm lua/*.ljbc
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/2c8bac712cf64898b4d4cacb7c773cc7.jpg)
停止服务器。
kill -QUIT `cat logs/nginx.pid`
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/cceec4d4c111407cbb36198ddc769241.jpg)
再次启动服务器。
time openresty -p $PWD/
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/56fee648efec424497d359d619cc3958.jpg)
这次是 17毫秒!我们可以通过加载 Lua 源文件看到它也慢了 10毫秒。
最后,也可以尝试删除 Lua 源文件。
rm lua/*.lua
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/fa997ef1dcfd406bb9ea56592f41ed22.jpg)
停止服务器并重新启动它。
time openresty -p $PWD/
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/3d48449f15fd42b7bb80b67d5daf3427.jpg)
这一次,我们得到了一个预期的错误,因为两个版本的模块都不见了。
对于小的 Lua 模块文件,加载它们的源代码已经非常快了。
echo 'local _M = {} function _M.foo() end return _M' > a.lua
ls -l a.lua
time resty -I. -e 'require "a"'
![预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度](https://image.cha138.com/20210403/dede0bd92eba42df86a2905f485c1681.jpg)
预编译一个小的 Lua 模块文件不会有太大的帮助。
time /usr/local/openresty/luajit/bin/luajit -bg a.lua a.ljbc
time resty -I. -e 'require "a"'
确实不多。但如果你有很多小模块要加载,节省的时间会很快积累起来。
如果你喜欢这个视频,请订阅我们的 YouTube 频道 或 B 站频道。谢谢!
关于本文和关联视频
本文和相关联的视频都是完全由我们的 OpenResty Demo 系统从一个极简单的剧本文件自动生成的。
关于作者
章亦春是开源项目 OpenResty® 的创始人,同时也是 OpenResty Inc. 公司的创始人和 CEO。他贡献了许多 Nginx 的第三方模块,相当多 Nginx 和 LuaJIT 核心补丁,并且设计了 OpenResty XRay 等产品。
关注我们
翻译
我们提供了英文版原文和中译版(本文) 。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!
以上是关于预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度的主要内容,如果未能解决你的问题,请参考以下文章