轉 https://qinguan.github.io/2018/04/12/some-tips-about-openresty-lua/
關於openresty lua使用的一些tips
nginx 是多 worker 進程的模型,所以除了共享內存字典是所有 worker 進程共享之外,其他的數據都是每 worker 一份的,無論是在 init_by_lua 裏面創建的全局變量,還是 Lua 模塊裏的狀態變量。
在某個請求裏面更新某個 Lua 變量,只是更新了當前處理這個請求的 nginx worker 進程裏的狀態,並不會影響其他的 worker 進程(除非只配置了一個 nginx worker)。
Lua VM 是每一個 nginx worker 進程一份。這些獨立的 Lua VM 副本是從 nginx master 進程的 Lua VM 給 fork 出來的。而 init_by_lua 運行在 master 進程的 Lua VM 中,時間點發生在進程 fork 之前。
在共享內存字典中保存最新的數據,每個 worker 進程裏通過 Lua 模塊變量或者 init_by_lua 創建的全局變量
追蹤
當前 worker 裏實際使用的數據(worker需要不斷同共享內存的數據進行比較並更新)。關於上述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 | 關於變量共享的一個最小化配置: |