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. PageRank之基于C C#的基本实现

    重点不是说PageRank是什么,而是怎么用代码实现 什么是PageRank? PageRank,网页排名,又称网页级别.Google左侧排名或佩奇排名,是一种由[1]  根据网页之间相互的超链接计算 ...

  2. Django项目实战之用户上传与访问

    1 将文件保存到服务器本地 upload.html <!DOCTYPE html> <html lang="en"> <head> <me ...

  3. SQL Server 查询性能优化——创建索引原则(一)(转载)

    索引是什么?索引是提高查询性能的一个重要工具,索引就是把查询语句所需要的少量数据添加到索引分页中,这样访问数据时只要访问少数索引的分页就可以.但是索引对于提高查询性能也不是万能的,也不是建立越多的索引 ...

  4. 初探arch -小白安装arch篇

    前段时间突然想试一试arch系统,电脑有点拖不动了,想想可以自己DIY自己需要的东西,就装个arch吧. 于是就马不停蹄的安装. 1.开始:用U盘制作启动盘.这里推荐低量级的制作软件USBwriter ...

  5. [LeetCode] Find Smallest Letter Greater Than Target 找比目标值大的最小字母

    Given a list of sorted characters letters containing only lowercase letters, and given a target lett ...

  6. [LeetCode] IPO 上市

    Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Cap ...

  7. angularjs中使用 <input type="file">标签实现一次最多上传5张图片

    前期准备: 1.angular.js 2.bootstrap.css 具体如何实现呢?请看下面代码哈哈哈. 在angular项目中,如果要给<input type="file" ...

  8. Python数据类型和数据操作

    python数据类型有:int,float,string,boolean类型.其中string类型是不可变变量,用string定义的变量称为不可变变量,该变量的值不能修改. 下面介绍python中的l ...

  9. [SDOI2011]消耗战

    题目描述 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望.已知 ...

  10. 洛谷3794 签到题IV

    题目描述 给定一个长度为n的序列$a_1,a_2...a_n$,其中每个数都是正整数. 你需要找出有多少对(i,j),$1 \leq i \leq j \leq n$且$gcd(a_i,a_{i+1} ...