This tutorial will demonstrate how to share data across different HTTP requests served by an OpenResty application.

1
2
3
4
5
cd ~/
mkdir data-share
cd data-share/
mkdir conf logs lua
tree

screenshot 1

We first prepare our test application’s directory tree.

The easist way to share data among requests is to use a custom Lua module named lua/my-module.lua.

We make the following edits:

  1. We add a global counter variable on the top-level of this module.
  2. Then we always increment this counter in a module function named main.
  3. and return the new counter value.
1
2
3
4
5
6
7
8
9
10
local _M = {}

local counter = 0

function _M.main()
counter = counter + 1
return counter
end

return _M

screenshot 6

Now let’s quickly craft the nginx configuration file, conf/nginx.conf.

We make the following edits:

  1. Here we specify where to look for our Lua module.
  2. Then define a server listening on the local 8080 port.
  3. And a root location with content_by_lua_block.
  4. Load up our Lua module and invoke its main function.
  5. And output the returned counter value as the response body.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
worker_processes 1;

events {
worker_connections 1024;
}

http {
lua_package_path "$prefix/lua/?.lua;;";

server {
listen 8080;

location / {
default_type text/plain;
content_by_lua_block {
local mod = require "my-module"
local cnt = mod.main()
ngx.say("counter = ", cnt)
}
}
}
}

screenshot 13

Let’s check the directory tree again.

1
tree .

screenshot 15

Looking good.

Start this OpenResty application without sudo.

1
openresty -p $PWD/

screenshot 17

Here we only enable a single worker process.

1
ps aux|grep nginx|grep -v tmp

screenshot 18

Send an HTTP request to the server using curl:

1
curl 'http://127.0.0.1:8080/'

screenshot 19

The counter value is 1.

Again.

screenshot 21

Cool, it’s 2 now.

It will only keep growing.

screenshot 23

This counter Lua variable is shared because it is an up value (upvalue) of the Lua module function.

1
cat lua/my-module.lua

screenshot 24

And the Lua module is cached and shared in the global LuaJIT virtual machine.

1
resty -Ilua -e 'require "my-module" print(package.loaded["my-module"].main)'

screenshot 25

See? We can also access the cached Lua module directly.

The package.loaded global table holds all the loaded Lua modules.

1
resty -e 'for k, v in pairs(package.loaded) do print(k) end'

screenshot 27

Here, most of the modules are those standard ones.

There is a limitation, however. Such data cannot be shared among different nginx worker processes.

screenshot 29

It’s not a problem here because only 1 worker process is configured.

But usually we would utilize multiple CPU cores by enabling multiple worker processes.

1
worker_processes 4;

screenshot 31

Then each worker process would have its own counter.

Let’s test the configuration and then reload the server.

1
2
openresty -p $PWD/ -t
kill -HUP `cat logs/nginx.pid`

screenshot 33

Now we should have 4 worker processes.

1
ps aux|grep nginx|grep -v tmp

screenshot 34

So this Lua module data sharing approach is mostly useful for Lua level data caching.

The resty.lrucache Lua module shipped with OpenResty is designed for such use cases.

1
restydoc resty.lrucache

screenshot 36

We will cover this module in a future tutorial.

If we want to share data across all the worker processes, we should use the Lua shared memory dictionaries instead.

1
2
restydoc -s lua_shared_dict
restydoc -s ngx.shared.DICT

screenshot 38

We will cover this topic in another dedicated tutorial.

That’s all I’d like to cover today. Happy hacking!

If you like this tutorial, please subscribe to this blog site and our YouTube channel. Thank you!

About This Article and Associated Video

This article and its associated video are both generated automatically from a simple screenplay file.

About The Author

Yichun Zhang is the creator of the OpenResty® open source project. He is also the founder and CEO of the OpenResty Inc. company. He contributed a dozen open source Nginx 3rd-party modules, quite some Nginx and LuaJIT core patches, and designed the OpenResty XRay platform.

Translations

We provide the Chinese translation for this article on blog.openresty.com.cn. We also welcome interested readers to contribute translations in other natural languages as long as the full article is translated without any omissions. We thank them in advance.

We are hiring

We always welcome talented and enthusiastic engineers to join our team at OpenResty Inc. to explore various open source software’s internals and build powerful analyzers and visualizers for real world applications built atop the open source software. If you are interested, please send your resume to talents@openresty.com . Thank you!