《OpenResty 安装与开发工具链》
OpenResty 是一个基于 Nginx 与 LuaJIT 的高性能 Web 平台,通过 Lua 脚本在 Nginx 各处理阶段实现业务逻辑。
1 简介
- 最佳实践(中文):https://moonbingbing.gitbooks.io/openresty-best-practices/
- LuaJIT gc64 模式:https://blog.openresty.com/en/luajit-gc64-mode/,开启后 Lua VM 寻址空间不再受限。
2 安装
以 Debian/Ubuntu 为例:
# 添加官方仓库
wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
echo "deb https://openresty.org/package/debian $(lsb_release -sc) main" \
> /etc/apt/sources.list.d/openresty.list
sudo apt-get update
sudo apt-get install -y openresty
或从源码编译:
wget https://openresty.org/download/openresty-1.21.4.2.tar.gz
tar zxf openresty-1.21.4.2.tar.gz
cd openresty-1.21.4.2
./configure --prefix=/usr/local/openresty
make -j$(nproc)
make install
3 使用 resty 二进制独立执行 Lua 代码
resty 可以直接启动一个临时的 nginx 并执行一段 Lua 代码,适合本地调试:
选项说明:
-I:指定 Lua 库目录--nginx:指定 nginx 二进制文件
resty -I /usr/local/nginx-front/lua --nginx /usr/local/nginx-front/sbin/nginx test.lua
test.lua 内容示例(发起一个 HTTP 请求):
local http = require("resty.http")
local http_new = http.new
local function main()
local client = http_new()
local res, err = client:request_uri("https://example.com", {
method = "GET",
keepalive_timeout = 60,
keepalive_pool = 10,
}
)
if err then
print("error: ", err)
else
print(res.status)
print(res.body)
end
end
main()
注意:这段代码直接用 resty 执行没问题,但如果放到 nginx 配置里运行,DNS 无法解析,需要添加 resolver 指令:
location = /hello {
resolver 127.0.0.1;
content_by_lua_block {
local http = require("resty.http")
local http_new = http.new
local function main()
local client = http_new()
local res, err = client:request_uri("https://example.com", {
method = "GET",
keepalive_timeout = 60,
keepalive_pool = 10,
}
)
if err then
ngx.say("error: ", err)
else
ngx.say(res.status)
ngx.say(res.body)
end
end
main()
}
}
4 静态检查:luacheck
安装:
luarocks install luacheck
.luacheckrc 示例(该文件本身就是 Lua 代码):
cache = true
std = 'ngx_lua'
ignore = {
"_", -- 忽略 _ 变量,我们用它来表示没有用到的变量
-- "6..", -- 忽略格式上的 warning
}
globals = {
-- 标记 ngx.header 和 ngx.status 可以被写入
"ngx",
}
-- 不检查来自第三方的代码库
exclude_files = {
"nginx/resty",
}
在提交代码之前执行 luacheck 做静态检查,可加入 git pre-commit 钩子:
#!/usr/bin/env bash
lua_files=$(git status -s|awk '{if (($1=="M"||$1=="A") && $2 ~ /.lua$/)print $2;}')
if [[ "$lua_files" != "" ]]; then
result=$(luacheck $lua_files)
if [[ "$result" =~ .*:.*:.*: ]]; then
echo "$result"
echo ""
exec < /dev/tty
read -p "Abort commit?(Y/n)"
if [[ "$REPLY" == y* ]] || [[ "$REPLY" == Y* ]]; then
echo "Abort commit"
exit 1
fi
fi
fi
记得给 pre-commit 文件加上可执行权限。
5 单元测试代码覆盖率(luacov)
luacov 可以统计 OpenResty 单元测试的覆盖率:
- 说明:https://github.com/moonbingbing/openresty-best-practices/blob/master/test/coverage.md
- 框架:https://keplerproject.github.io/luacov/doc/index.html
常见问题:
-
找不到 lustache 模块
lua: ...lualib/luacov/reporter/multiple/html.lua:3: module 'lustache' not found通过 luarocks 安装:
luarocks install lustache -
找不到 lfs 模块
lua: ...lualib/luacov/reporter/multiple/html.lua:2: module 'lfs' not found将系统已有的
lfs.so软链到 nginx 能找到的目录:ln -s /usr/lib/x86_64-linux-gnu/liblua5.1-filesystem.so.0.0.0 /usr/local/lib/lua/5.1/lfs.so
6 使用 gdb 调试 coredump
借助 openresty-gdb-utils 调试 coredump:
安装(在 gdb 中加载):
directory /path/to/openresty-gdb-utils
py import sys
py sys.path.append("/path/to/openresty-gdb-utils")
source luajit20.gdb
source ngx-lua.gdb
source luajit21.py
source ngx-raw-req.py
set python print-stack full
相关调试方法也可参考《OpenResty 性能与稳定性排查》一文中的 coredump 章节。
阅读 —
·
全站 —