关于openresty lua使用的一些tips

转 https://qinguan.github.io/2018/04/12/some-tips-about-openresty-lua/


关于openresty lua使用的一些tips

 
       

  1. nginx 是多 worker 进程的模型,所以除了共享内存字典是所有 worker 进程共享之外,其他的数据都是每 worker 一份的,无论是在 init_by_lua 里面创建的全局变量,还是 Lua 模块里的状态变量。

  2. 在某个请求里面更新某个 Lua 变量,只是更新了当前处理这个请求的 nginx worker 进程里的状态,并不会影响其他的 worker 进程(除非只配置了一个 nginx worker)。

  3. Lua VM 是每一个 nginx worker 进程一份。这些独立的 Lua VM 副本是从 nginx master 进程的 Lua VM 给 fork 出来的。而 init_by_lua 运行在 master 进程的 Lua VM 中,时间点发生在进程 fork 之前。

  4. 在共享内存字典中保存最新的数据,每个 worker 进程里通过 Lua 模块变量或者 init_by_lua 创建的全局变量追踪当前 worker 里实际使用的数据(worker需要不断同共享内存的数据进行比较并更新)。

  5. 关于上述1、2、3、4点,更多请参考:

lua_code_cache的使用

  • 关闭lua_code_cache, 则每一个请求都由一个独立的lua VM来处理。因此,通过A请求变更的lua数据(如模块变量),不会被B请求解析到,即使只配置了一个。

  • 关闭lua_code_cache的好处,对于纯lua文件(不涉及nginx解析的),在不重启nginx的情况下也能立即生效。

  • 启用lua_code_cache, 则同一个worker的所有请求共享一个lua VM的数据。因此,由该worker处理的A请求变更了lua数据(如模块变量),则会被同一个worker处理的B请求访问到。

  • 生产环境强烈建议启用lua_code_cache,否则会带来较大的性能损失。

  • 更多参考 这里

关于lua变量共享问题

不应使用模块级的局部变量以及模块属性,存放任何请求级的数据。否则在 luacodecache 开启时,会造成请求间相互影响和数据竞争,产生不可预知的异常状况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
关于变量共享的一个最小化配置:
-- share.lua
local _M={}
local data = {}

function _M.get_value(key)
   return data[key]
end
function _M.set_value(key,value)
   data[key] = value
end

return _M

### server.conf
server {
   listen 8081;
   server_name 127.0.0.1;

   ### 通过请求A设置模块共享变量
   location = /1 {
       content_by_lua_block {
           local share = require('share')
           share.set_value('a','b')
           ngx.say(share.get_value('a'))
       }
   }

   ### 通过请求B读取共享变量
   location = /2 {
       content_by_lua_block {
           local share = require('share')
           ngx.say(share.get_value('a'))
       }
   }
}

-- init.lua
package.path = "/usr/local/Cellar/openresty/1.13.6.1/lualib/?.lua;/usr/local/etc/openresty/lua/?.lua;;";

### nginx 主配置文件部分内容
http {
   include       mime.types;
   default_type  application/octet-stream;

   log_format main '$remote_addr - [$time_local] "$request" $status '
   ' "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ';

   access_log  logs/access.log  main;
   sendfile        on;
   keepalive_timeout  60;
   include server.conf;
   lua_code_cache on;
   init_by_lua_file lua/init.lua;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章