在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
环境: 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 输出
也就是说,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 输出
这里,在子请求中修改 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 将输出
而不是原始的 "hello" 值。 任意数据值,包括 Lua 闭包与嵌套表,都可以被插入这个“魔法”表,也允许注册自定义元方法。 也可以将 ngx.ctx 覆盖为一个新 Lua 表,例如,
当用在 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 表调用应通过函数传参方式完成。 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对极客世界的支持。 |
请发表评论