预编译 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/
截图1

这里我们将使用一个大的Lua模块文件pkg-stap.lua。它是由我们的 opslang 编译器生成的。

cp ~/git/opslang/pkg-stap.lua ./
ls -lh *.lua
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图2

我们可以看到,这个Lua模块是 1.6MB。

让我们尝试用resty工具加载这个 Lua 模块。

time resty -I. -e 'require "pkg-stap"'
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图4

一共需要 23毫秒。

让我们检查一下运行一个空的 Lua 程序的原始开销。

time resty -e ''
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图6

大约是 11毫秒。所以加载模块本身大约需要 12毫秒。

让我们尝试将 Lua 模块预编译成 LuaJIT 字节码。

time /usr/local/openresty/luajit/bin/luajit -bg pkg-stap.lua pkg-stap.ljbc
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图8

这里我们使用 OpenResty 的luajit程序。

它生成一个 LuaJIT 字节码文件,文件扩展名为.ljbc

ls -lh *.ljbc
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图10

看到字节码文件也小了 50% 以上,很有意思!

然后再尝试用resty加载。

time resty -I. -e 'require "pkg-stap"'
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图12

总共只有 13毫秒!

现在几乎就像加载一个空的 Lua 程序一样!只多了 2毫秒。

time resty -e ''
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图14

当加载一个模块时,"resty" 工具总是试图在 ".lua" 文件之前加载一个 ".ljbc" 文件。

让我们看看如何让它在 OpenResty 服务器上工作。

mkdir conf logs lua
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图16

将我们的 Lua 模块文件复制到lua/子目录下。

mv *.lua *.ljbc lua/
tree .
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图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 "; }
}
}

检查目录树。

tree .
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图26

看起来不错!

尝试使用-t选项测试服务器配置。

time openresty -p $PWD/ -t

启动它。

time openresty -p $PWD/
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图29

约 7毫秒。

尝试删除 LuaJIT 字节码文件。

rm lua/*.ljbc
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图31

停止服务器。

kill -QUIT `cat logs/nginx.pid`
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图32

再次启动服务器。

time openresty -p $PWD/
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图33

这次是 17毫秒!我们可以通过加载 Lua 源文件看到它也慢了 10毫秒。

最后,也可以尝试删除 Lua 源文件。

rm lua/*.lua
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图35

停止服务器并重新启动它。

time openresty -p $PWD/
预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度
截图36

这一次,我们得到了一个预期的错误,因为两个版本的模块都不见了。

对于小的 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 启动速度
截图38

预编译一个小的 Lua 模块文件不会有太大的帮助。

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

确实不多。但如果你有很多小模块要加载,节省的时间会很快积累起来。

如果你喜欢这个视频,请订阅我们的 YouTube 频道 或 B 站频道。谢谢!

关于本文和关联视频

本文和相关联的视频都是完全由我们的 OpenResty Demo 系统从一个极简单的剧本文件自动生成的。

关于作者

章亦春是开源项目 OpenResty® 的创始人,同时也是 OpenResty Inc. 公司的创始人和 CEO。他贡献了许多 Nginx 的第三方模块,相当多 Nginx 和 LuaJIT 核心补丁,并且设计了 OpenResty XRay 等产品。

关注我们

我们的微信公众号

翻译

我们提供了英文版原文和中译版(本文) 。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!

以上是关于预编译 Lua 模块到 LuaJIT 字节码中以加快 OpenResty 启动速度的主要内容,如果未能解决你的问题,请参考以下文章

最新LuaJIT 32/64 位字节码,从编译到使用全纪录

最新LuaJIT 32/64 位字节码,从编译到使用全纪录

luajit与NYI

cocos2dx 用luajit 加密脚本 会被反编译吗

Nginx编译安装Lua模块

使用tengine DSO 来动态编译安装第三方模块(Lua