關於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;
}


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