Nginx uses ctx to realize data sharing and context modification functions

Nginx uses ctx to realize data sharing and context modification functions

Environment: 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 Lua table can be used to store request-based Lua environment data, and its lifetime is the same as the current request (similar to Nginx variables).

Refer to the following example,

 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)
  }
 }

Access GET /test Output

79

That is, the ngx.ctx.foo entry remains consistent across the rewrite, access, and content processing phases of a request.

Each request, including subrequests, has its own copy of the ngx.ctx table. For example:

 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)
  }
 }

Access GET /main output

Main pre: 73
sub pre: nil
sub post: 32
main post: 73

Here, modifying the ngx.ctx.blah entry in the child request does not affect the entry with the same name in the parent request, because they each maintain a different version of ngx.ctx.blah.

Internal redirection will destroy the ngx.ctx data in the original request (if any), and the new request will have a blank ngx.ctx table. For example,

 location /new {
  content_by_lua_block {
   ngx.say(ngx.ctx.foo)
  }
 }

 location /orig {
  content_by_lua_block {
   ngx.ctx.foo = "hello"
   ngx.exec("/new")
  }
 }

Accessing GET /orig will output

nil

instead of the original "hello" value.

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

It is also possible to overwrite ngx.ctx with a new Lua table, for example,

ngx.ctx = { foo = 32, bar = 54 }

When used in an init_worker_by_lua* context, this table has the same lifetime as the current Lua handle.

ngx.ctx table lookups require relatively expensive metamethod calls, which are much slower than passing request-based data directly via user's own function arguments. So do not abuse this API to save user function parameters, as it may have a significant impact on performance.

And because of metamethod "magic", don't try to use "local" level ngx.ctx at lua module level, for example for worker-level data sharing. The following example is bad:

-- mymodule.lua

local _M = {}

-- The ngx.ctx in the following line belongs to a single request, but the ctx variable is at the Lua module level

-- and belongs to a single worker.

 local ctx = ngx.ctx

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

 return _M

The following should be used instead:

 -- mymodule.lua
 local _M = {}

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

 return _M

That is to say, the caller should complete the call to the ctx table by passing parameters to the function.

Summarize

The above is the full content of this article. I hope that the content of this article will have certain reference learning value for your study or work. If you have any questions, you can leave a message to communicate. Thank you for your support for 123WORDPRESS.COM.

You may also be interested in:
  • Example of shared session configuration method in Nginx
  • Nginx load balancing multi-site shared session
  • nginx+tomcat implements load balancing and uses redis session sharing
  • nginx+redis realizes session sharing

<<:  React Hooks Usage Examples

>>:  Detailed tutorial on customizing the installation path of MySQL 5.7.18 version (binary package installation)

Recommend

Detailed explanation of pure SQL statement method based on JPQL

JPQL stands for Java Persistence Query Language. ...

A general method for implementing infinite text carousel with native CSS

Text carousels are very common in our daily life....

How to use map to allow multiple domain names to cross domains in Nginx

Common Nginx configuration allows cross-domain se...

Master the CSS property display:flow-root declaration in one article

byzhangxinxu from https://www.zhangxinxu.com/word...

Docker online and offline installation and common command operations

1. Test environment name Version centos 7.6 docke...

Gradient slide effect implemented by CSS3

Achieve results Code html <div class="css...

mysql implements the operation of setting multiple primary keys

User table, ID number must be unique, mobile phon...

Mysql uses insert to insert multiple records to add data in batches

If you want to insert 5 records into table1, the ...

Website background music implementation method

For individual webmasters, how to make their websi...

Example of usage of keep-alive component in Vue

Problem description (what is keep-alive) keep-ali...

display:grid in CSS3, an introduction to grid layout

1. Grid layout (grid): It divides the web page in...

Node.js+express message board function implementation example

Table of contents Message Board Required librarie...

Detailed explanation of how to synchronize data from MySQL to Elasticsearch

Table of contents 1. Synchronization Principle 2....

Media query combined with rem layout in CSS3 to adapt to mobile screens

CSS3 syntax: (1rem = 100px for a 750px design) @m...

Summary of the use of MySQL date and time functions

This article is based on MySQL 8.0 This article i...