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

Common methods and problems of Docker cleaning

If you use docker for large-scale development but...

Detailed explanation of JSONObject usage

JSONObject is just a data structure, which can be...

Summary of MySQL commonly used type conversion functions (recommended)

1. Concat function. Commonly used connection stri...

Vue routing relative path jump method

Table of contents Vue routing relative path jump ...

Use vertical-align to align input and img

Putting input and img on the same line, the img ta...

20 CSS coding tips to make you more efficient (sorted)

In this article, we would like to share with you ...

Implementing form submission without refreshing the page based on HTML

Using ajax to implement form submission without re...

How to use node to implement static file caching

Table of contents cache Cache location classifica...

Docker image creation Dockerfile and commit operations

Build the image There are two main ways to build ...

JavaScript Advanced Custom Exception

Table of contents 1. Concept 1.1 What are errors ...

Example code for implementing background transparency and opaque text with CSS3

Recently, I encountered a requirement to display ...

Detailed steps for installing and using vmware esxi6.5

Table of contents Introduction Architecture Advan...

Vue implements user login switching

This article example shares the specific code of ...