Question:
現(xiàn)在有一個場景:需要定時(30s)從redis里面拉取數(shù)據(jù)灌入 lua cache 共享內(nèi)存。我現(xiàn)在是用 ngx.timer 這個 API 來實現(xiàn)的,請問這會不會有問題?因為對 ngx.timer 這個 API 不是很了解看了文檔說是:在后臺開啟了一個輕量級線程來執(zhí)行,與原來的請求脫鉤。場景需求是拉取灌入的操作不能阻塞 worker 。
Answer:
請問這樣能夠滿足需求嗎?會不會有阻塞問題?
只要使用的都是 OpenResty 的 API 和庫,是不存在阻塞問題的。只要大體確認一下當前 nginx 進程負載壓力不要太高,能夠確定獲取到工作時間片即可。
有沒有可以開啟 worker 的時候就啟動 timer 的辦法 。。。
其實這里你已經(jīng)點出關(guān)鍵字了,借助 init_worker_by_lua 即可。
這個 timer 是每個 worker 里面都會有還是只有一個 worker 。。。
通過 init_worker_by_lua 啟動的 ngx.timer 是對每個 worker 的。如果這里需要控制 timer 的存在數(shù)量,可以借助 ngx.worker.id 完成 ngx.timer 數(shù)量控制,比如只啟動一個或多個,并讓他們確定綁定在哪個 worker 上。
Question: 如題
Answer:
如果你想在 Lua 中通過標準 Lua API os.getenv 來訪問系統(tǒng)環(huán)境變量,例如 foo
, 那么你需要在你的 nginx.conf 中,通過 env 指令,把這個環(huán)境變量列出來。 例如:
env foo;
Question
這個庫的使用流程大致如下:
1. 創(chuàng)建一個 mongo 對象(local conn =mongo:new())
2. 創(chuàng)建一個連接 mongodb(conn:connect("192.168.1.254",27017))
3. 選擇數(shù)據(jù)庫(local db = conn:new_db_handle("openresty"))
4. 然后 auth 驗證(db:auth_scram_sha1("username","password"))
5. 接收數(shù)據(jù)執(zhí)行 insert 操作
6. 放入連接池(conn:set_keepalive(10000, 100))
主要問題是用戶登錄部分占用將近 1/3 的時間,這個合理么?如何優(yōu)化?
Answer
為了回答上面的問題,我們先粗略整理一下數(shù)據(jù)庫連接池的通常做法,看下面流程圖:
http://wiki.jikexueyuan.com/project/openresty/images/summy_list_20160801.png" alt="" />
主要區(qū)別:如何減少不必要的用戶驗證過程,合理高效的復用已有連接。其實對于已經(jīng)驗證過的連接,直接使用即可。
比較推薦的改進方法,參考 lua-resty-mysql 的實現(xiàn),對不同 ip、port、db、user、password 綁定不同的連接池名字,讓不同連接目的連接歸類存放,并在數(shù)據(jù)庫層直接完成用戶驗證動作。
Question:如題
Answer:
是可以借用 jit.v 或者 jit.dump 這兩個 lua 模塊可以輸出 NYI 等日志。它們都是 luajit 自帶的標準模塊,在針對 jit 編譯器做 lua 代碼優(yōu)化時,這兩個模塊之一是必須的。具體用法可以參考 lua-resty-core 項目的測試集。
jit.dump 輸出的信息最詳盡,從 trace 的 bc 到 ir 再到 mcode,jit.v 則比較簡略。書鑫老師正在做一個更好的 luajit IR dumper,jit.dump 目前輸出的 IR 列表不夠直觀,不夠友好。書鑫老師的 IR 輸出看著像高級語言偽碼。
引用一下 lua-resty-core/t/md5.t 的第一個測試用例,為了突出重點,這里做了一下節(jié)選:
our $HttpConfig = <<_EOC_;
lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;";
init_by_lua_block {
local v = require "jit.v"
v.on("$Test::Nginx::Util::ErrLogFile")
require "resty.core"
}
_EOC_
__DATA__
=== TEST 1: set md5 hello
--- http_config eval: $::HttpConfig
--- config
location = /md5 {
content_by_lua_block {
local s
for i = 1, 100 do
s = ngx.md5("hello")
end
ngx.say(s)
}
}
--- request
GET /md5
--- response_body
5d41402abc4b2a76b9719d911017c592
--- error_log eval
qr/\[TRACE 1 content_by_lua\(nginx\.conf:\d+\):3 loop\]/
--- no_error_log
[error]
解釋一下,對是否執(zhí)行了 LuaJIT 優(yōu)化編譯,最后是通過 error_log eval
這個小節(jié)匹配確定的。這是預期的一條被 JIT 優(yōu)化編譯的日志輸出結(jié)果。
而對于沒有被 JIT 編譯優(yōu)化,是有下面類似日志輸出的,會出現(xiàn) NYI(Not Yet Implemented) 關(guān)鍵字,比如下面:
[TRACE --- db_base.lua:247 -- NYI: bytecode 51 at db_base.lua:252]
有興趣的同學,可以自己玩下 jit.dump ,對匯編比較了解的同學,有驚喜哦。