您好,欢迎访问一九零五行业门户网

nginx怎么使用ctx实现数据共享

环境: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer., balancer_by_lua
这个 lua 表可以用来存储基于请求的 lua 环境数据,其生存周期与当前请求相同 (类似 nginx 变量)。
参考下面例子,
location /test {
     rewrite_by_lua_block {
         ngx.ctx.foo = 76
     }
     access_by_lua_block {
         ngx.ctx.foo = ngx.ctx.foo + 3
     }
     content_by_lua_block {
         ngx.say(ngx.ctx.foo)
     }
 }
访问 get /test 输出
79
也就是说,ngx.ctx.foo 条目跨越一个请求的 rewrite (重写),access (访问),和 content (内容) 各处理阶段保持一致。
每个请求,包括子请求,都有一份自己的 ngx.ctx 表。例如:
location /sub {
     content_by_lua_block {
         ngx.say(sub pre: , ngx.ctx.blah)
         ngx.ctx.blah = 32
         ngx.say(sub post: , ngx.ctx.blah)
     }
 }
 location /main {
     content_by_lua_block {
         ngx.ctx.blah = 73
         ngx.say(main pre: , ngx.ctx.blah)
         local res = ngx.location.capture(/sub)
         ngx.print(res.body)
         ngx.say(main post: , ngx.ctx.blah)
     }
 }
访问 get /main 输出
main pre: 73
sub pre: nil
sub post: 32
main post: 73
这里,在子请求中修改 ngx.ctx.blah 条目并不影响父请求中的同名条目,因为它们各自维护不同版本的 ngx.ctx.blah。
内部重定向将摧毁原始请求中的 ngx.ctx 数据 (如果有),新请求将会有一个空白的 ngx.ctx 表。例如,
location /new {
     content_by_lua_block {
         ngx.say(ngx.ctx.foo)
     }
 }
 location /orig {
     content_by_lua_block {
         ngx.ctx.foo = hello
         ngx.exec(/new)
     }
 }
访问 get /orig 将输出
nil
而不是原始的 hello 值。
任意数据值,包括 lua 闭包与嵌套表,都可以被插入这个“魔法”表,也允许注册自定义元方法。
也可以将 ngx.ctx 覆盖为一个新 lua 表,例如,
ngx.ctx = { foo = 32, bar = 54 }
当用在 init_worker_by_lua* 环境中,这个表与当前 lua 句柄生命周期相同。
ngx.ctx 表查询需要相对昂贵的元方法调用,这比通过用户自己的函数参数直接传递基于请求的数据要慢得多。所以不要为了节约用户函数参数而滥用此 api,因为它可能对性能有明显影响。
而且由于元方法“魔法”,不要在 lua 模块级别试图使用 local 级别的 ngx.ctx ,例如 worker-level data sharing。下面示例是糟糕的:
-- mymodule.lua
local _m = {}
-- 下面一行的 ngx.ctx 是属于单个请求的,但 ctx 变量是在 lua 模块级别
-- 并且属于单个 worker 的。
local ctx = ngx.ctx
 function _m.main()
     ctx.foo = bar
 end
 return _m
应使用下面方式替代:
-- mymodule.lua
 local _m = {}
 function _m.main(ctx)
     ctx.foo = bar
 end
 return _m
就是说,调用者对 ctx 表调用应通过函数传参方式完成。
以上就是nginx怎么使用ctx实现数据共享的详细内容。
其它类似信息

推荐信息