在 OpenResty 中跨请求共享数据
本教程将逐步演示如何在OpenResty应用程序服务的不同HTTP请求中共享数据。
1 | cd ~/ |
我们首先准备测试应用程序的目录树。
在请求之间共享数据的简单方法是使用一个名为lua/my-module.lua
的自定义Lua模块。
我们进行以下编辑:
- 我们在这个模块的顶层增加一个全局计数器变量。
- 然后我们总是在一个名为
main
的模块函数中递增这个计数器。 - 并返回新的计数器值。
1 | local _M = {} |
现在让我们快速制作nginx配置文件,conf/nginx.conf
。
我们进行以下编辑:
1.在这里,我们指定在哪里寻找我们的Lua模块。
2.然后在本地8080端口上定义一个监听服务器。
3.而根位置下有content_by_lua_block
。
4.加载我们的Lua模块并调用它的 main
函数。
5.并将返回的计数器值作为响应体输出。
1 | worker_processes 1; |
我们再来检查一下目录树。
1 | tree . |
看起来不错。
在没有sudo
的情况下启动这个OpenResty应用程序。
1 | openresty -p $PWD/ |
在这里,我们只启用一个工作进程。
1 | ps aux|grep nginx|grep -v tmp |
使用curl
向服务器发送HTTP请求。
1 | curl 'http://127.0.0.1:8080/' |
计数器的值是1。
再来一次:
酷,现在是2。
它只会不断增长。
这个 counter
Lua变量是共享的,因为它是Lua模块函数的 “up value”(upvalue)。
1 | cat lua/my-module.lua |
而Lua模块在全局LuaJIT虚拟机中被缓存和共享。
1 | resty -Ilua -e 'require "my-module" print(package.loaded["my-module"].main)' |
看到了吗?我们也可以直接访问缓存的Lua模块。
package.load
全局表保存了所有加载的Lua模块。
1 | resty -e 'for k, v in pairs(package.loaded) do print(k) end' |
在这里,大部分的模块都是那些标准的模块。
但是有一个限制。这些数据不能在不同的nginx工作进程之间共享。
这里没有问题,因为只配置了1个工作进程。
但通常我们会通过启用多个工作进程来利用多个CPU核心。
1 | worker_processes 4; |
那么每个工作进程都会有自己的计数器。
让我们测试配置,然后重新加载服务器。
1 | openresty -p $PWD/ -t |
现在我们应该有4个工作进程。
1 | ps aux|grep nginx|grep -v tmp |
所以这种Lua模块数据共享的方式主要是用于Lua级别的数据缓存。
与OpenResty一起提供的resty.lucache Lua模块就是为这样的场景设计的。
1 | restydoc resty.lrucache |
我们将在以后的教程中介绍这个模块。
如果我们想在所有工作进程中共享数据,我们应该使用Lua共享内存字典来代替。
1 | restydoc -s lua_shared_dict |
我们将在另一个专门的教程中介绍这个话题。
今天我想介绍的就这么多。祝编程愉快!
如果你喜欢这个视频,请订阅我们的 YouTube 频道 或 B 站频道。谢谢!
关于本文和关联视频
本文和相关联的视频都是完全由我们的 OpenResty Demo 系统从一个极简单的剧本文件自动生成的。
关于作者
章亦春是开源项目 OpenResty® 的创始人,同时也是 OpenResty Inc. 公司的创始人和 CEO。他贡献了许多 Nginx 的第三方模块,相当多 Nginx 和 LuaJIT 核心补丁,并且设计了 OpenResty XRay 等产品。
关注我们
如果您觉得本文有价值,非常欢迎关注我们 OpenResty Inc. 公司的博客网站 。也欢迎扫码关注我们的微信公众号:
翻译
我们提供了英文版原文和中译版(本文) 。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!