https://github.com/openresty/lua-nginx-module#ngxctx

要点

  1. 生命周期和请求一致
  2. 每个请求的ngx.ctx是相互独立的,包括ngx.location.capture的子请求
  3. 内部跳转(Internal redirection)如ngx.exec会销毁ngx.ctx,重建新的.
  4. ngx.ctx的属性查找代价相对昂贵,所以尽量使用显式的函数参数.

原文

context: 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*

This table can be used to store per-request Lua context data and has a life time identical to the current request (as with the Nginx variables).

Consider the following example,

location /test {
rewrite_by_lua '
ngx.ctx.foo = 76
';
access_by_lua '
ngx.ctx.foo = ngx.ctx.foo + 3
';
content_by_lua '
ngx.say(ngx.ctx.foo)
';
}
Then GET /test will yield the output

79
That is, the ngx.ctx.foo entry persists across the rewrite, access, and content phases of a request.

Every request, including subrequests, has its own copy of the table. For example:

location /sub {
content_by_lua '
ngx.say("sub pre: ", ngx.ctx.blah)
ngx.ctx.blah = 32
ngx.say("sub post: ", ngx.ctx.blah)
';
}

location /main {
content_by_lua '
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)
';
}
Then GET /main will give the output

main pre: 73
sub pre: nil
sub post: 32
main post: 73
Here, modification of the ngx.ctx.blah entry in the subrequest does not affect the one in the parent request. This is because they have two separate versions of ngx.ctx.blah.

Internal redirection will destroy the original request ngx.ctx data (if any) and the new request will have an empty ngx.ctx table. For instance,

location /new {
content_by_lua '
ngx.say(ngx.ctx.foo)
';
}

location /orig {
content_by_lua '
ngx.ctx.foo = "hello"
ngx.exec("/new")
';
}
Then GET /orig will give

nil
rather than the original "hello" value.

Arbitrary data values, including Lua closures and nested tables, can be inserted into this "magic" table. It also allows the registration of custom meta methods.

Overriding ngx.ctx with a new Lua table is also supported, for example,

ngx.ctx = { foo = 32, bar = 54 }
When being used in the context of init_worker_by_lua*, this table just has the same lifetime of the current Lua handler.

The ngx.ctx lookup requires relatively expensive metamethod calls and it is much slower than explicitly passing per-request data along by your own function arguments. So do not abuse this API for saving your own function arguments because it usually has quite some performance impact.

Because of the metamethod magic, never "local" the ngx.ctx table outside your Lua function scope on the Lua module level level due to worker-level data sharing. For example, the following is bad:

-- mymodule.lua
local _M = {}

-- the following line is bad since ngx.ctx is a per-request
-- data while this ctx variable is on the Lua module level
-- and thus is per-nginx-worker.
local ctx = ngx.ctx

function _M.main()
ctx.foo = "bar"
end

return _M
Use the following instead:

-- mymodule.lua
local _M = {}

function _M.main(ctx)
ctx.foo = "bar"
end

return _M
That is, let the caller pass the ctx table explicitly via a function argument.

ngx.ctx的更多相关文章

  1. nginx的 ngx.var ngx.ctx ngx.req

    ngx.var 是获取 Nginx 的变量,需要经历字符串 hash.hash 表查找等过程. ngx.ctx 仅仅是一个 Lua table 而已,它的引用存放在 ngx_lua 的模块上下文(ct ...

  2. nginx 使用ctx实现数据共享,修改上下文

    环境: init_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_ ...

  3. OpenResty之ngx.var.VARIABLE

    1. ngx.var.VARIABLE syntax: ngx.var.VAR_NAME context: set_by_lua*, rewrite_by_lua*, access_by_lua*, ...

  4. Nginx-ngx_lua模块原理和内置函数

    ngx_lua模块的原理: 1.每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM:2.将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问:3.每个 ...

  5. Openresty 与 Tengine

    Openresty 与 Tengine Openresty和Tengine基于 Nginx 的两个衍生版本,某种意义上他们都和淘宝有关系,前者是前淘宝工程师agentzh主导开发的,后者是淘宝的一个开 ...

  6. nginx lua mysql redis设置

    最近公司网站改版,程序和数据库全部用新版,旧版的数据要导入,旧网站的30万条数据url要全部重定向到新版网站,正好前段时间在学习nginx+lua+mysql+memcache(redis),找资料真 ...

  7. nginx记录响应与POST请求日志

    生产环境中的某些api出现故障,但是问题无法重现,但是又很想解决掉问题以及我们新项目上线,需要跟踪请求与响应的信息,可以预先找到一些bug,减少大面积的损失. 安装nginx与ngx_lua 响应日志 ...

  8. 【精选】Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解

    源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...

  9. 【精选】Nginx模块Lua-Nginx-Module学习笔记(二)Lua指令详解(Directives)

    源码地址:https://github.com/Tinywan/Lua-Nginx-Redis Nginx与Lua编写脚本的基本构建块是指令. 指令用于指定何时运行用户Lua代码以及如何使用结果. 下 ...

随机推荐

  1. [转]最常用的15大Eclipse开发快捷键技巧

    作者:Java我人生(陈磊兴)   原文出处http://blog.csdn.net/chenleixing/article/details/44600587 做Java开发的,经常会用Eclipse ...

  2. 【转】Python3中urllib详细使用方法(header,代理,超时,认证,异常处理)

      urllib是python的一个获取url(Uniform Resource Locators,统一资源定址器)了,我们可以利用它来抓取远程的数据进行保存哦,下面整理了一些关于urllib使用中的 ...

  3. 【转】cookielib模块

    cookielib模块 cookielib模块的主要作用是提供可存储cookie的对象,以便于与urllib2模块配合使用来访问Internet资源.例如可以利用本模块 的CookieJar类的对象来 ...

  4. SQL类型注入

    前言: 继续进行未完成的sql注入学习 今天学习了各类型注入.前来进行总结. 目录: 数字型注入 字符型注入 提交注注入 GET注入 POST注入 COOKIE注入 正文: 数字型注入:www.xxx ...

  5. [LeetCode] Employee Importance 员工重要度

    You are given a data structure of employee information, which includes the employee's unique id, his ...

  6. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用原型链和EventTrigger

    原型链是JS的必备,作为ECMAScript4,原型链也是支持的. 特别说明,ActionScript3是支持完整的面向对象继承支持的,原型链只在某些非常特殊的情况下使用. 本文旨在介绍如何使用原型链 ...

  7. python数据挖掘_Json结构分析

    json是一种轻量级的数据交换格式,也可以说是一种配置文件的格式 这种格式的文件是我们在数据处理经常会遇到的 python提供内置的模块json,只需要在使用前导入即可 你可以通过帮助函数查看json ...

  8. [ZJOI 2010]Perm 排列计数

    Description 题库链接 询问有多少个 \(1\sim N\) 的排列 \(P\) 满足" \(\forall i\in[2,N], P_i>P_{\frac{i}{2}}\) ...

  9. [USACO 06NOV]Corn Fields

    Description 题库链接 给你一个 \(0,1\) 矩阵,只准你在 \(1\) 上放物品:并且要满足物品不能相邻.允许空放,问方案数,取模. \(1\leq n,m\leq 12\) Solu ...

  10. Codeforces Round #460 E. Congruence Equation

    Description 题面 \(n*a^n≡b (\mod P),1<=n<=x\) Solution 令 \(n=(P-1)*i+j\) \([(P-1)*i+j]*a^{[(P-1) ...