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

How to reduce image size using Docker multi-stage build

This article describes how to use Docker's mu...

User experience of portal website redesign

<br />From the launch of NetEase's new h...

Basic ideas for finding errors in Web front-end development

WEB development mainly consists of two interactio...

The unreasonable MaxIdleConns of MySQL will cause short connections

1 Background Recently, some performance issues ha...

JavaScript uses setTimeout to achieve countdown effect

In order to enhance the ability to write JavaScri...

Why does MySQL paging become slower and slower when using limit?

Table of contents 1. Test experiment 2. Performan...

MySQL storage engine basics

In the previous article, we talked about MySQL tr...

JS implements Baidu search box

This article example shares the specific code of ...

About MYSQL, you need to know the data types and operation tables

Data Types and Operations Data Table 1.1 MySQL ty...

CSS realizes process navigation effect (three methods)

CSS realizes the process navigation effect. The s...

How to set mysql to case insensitive

mysql set to case insensitive Windows Go to the d...

Tutorial on using Docker Compose to build Confluence

This article uses the "Attribution 4.0 Inter...

How to solve the problem of forgetting the root password of Mysql on Mac

I haven't used mysql on my computer for a lon...