OpenResty

 9th November 2022 at 10:41am

OpenResty 官网首页,有非常详细的介绍:

OpenResty® is a full-fledged web platform that integrates our enhanced version of the Nginx core, our enhanced version of LuaJIT, many carefully written Lua libraries, lots of high quality 3rd-party Nginx modules, and most of their external dependencies. It is designed to help developers easily build scalable web applications, web services, and dynamic web gateways.

本质上是一个定制化的 nginx:

  • 给 nginx 修复了一些 bug,以 patch 形式维护了一个修复 bug 后的 nginx
  • 启用了大量第三方 nginx module
    • 其中主要是 Lua 相关的 module,也由 章亦春(agentzh)及 OpenResty 团队维护
    • Lua module 使用了 LuaJIT 2.x,也有一些 bug fix patch,与维护 nginx 的方式类似

OpenResty 不是一个 nginx fork。(淘宝的 Tengine 是)。

用 OpenResty 时 最主要是在用 lua-nginx-module。需要理解它。

并发模型

这个 StackOverflow 帖子提及了修改一个全局变量的例子。

TL;DR: OpenResty 底下的 nginx 使用的是 event-driven 模型,意味着只有一个线程在执行 OpenResty 的 lua 代码,因此读写全局变量时可以不采用并发控制(比如锁、信号量)。

调试方法

可以直接用 resty 命令行工具来运行 Lua 脚本。与 Lua 解释器的差别在于,resty 命令运行的脚本中可以使用 ngx table。

比如这样一个 redis_test.lua

local redis = require "resty.redis"
local red = redis:new()

red:set_timeouts(1000, 1000, 1000) -- 1 sec

-- connect via ip address directly
local ok, err = red:connect("127.0.0.1", 6379)

if not ok then
    ngx.say("failed to connect: ", err)
    return
end

local res, err = red:auth("test")
if not res then
    ngx.say("failed to authenticate: ", err)
    return
end

ok, err = red:set("dog", "an animal")
if not ok then
    ngx.say("failed to set dog: ", err)
    return
end

ngx.say("set result: ", ok)

local res, err = red:get("dog")
if not res then
    ngx.say("failed to get dog: ", err)
    return
end

if res == ngx.null then
    ngx.say("dog not found.")
    return
end

ngx.say("dog: ", res)

可以用 resty redis_test.lua 来运行它,会输出:

set result: OK
dog: an animal

技术细节没有深究。