2017-04-11 89 views
3

當發生某些情況時,我們需要從nginx將事件記錄到我們的事件服務器。我知道我可以使用access_by_lua進行http調用。由於事件記錄可能會失敗或需要更長時間,因此我們不希望請求處理等待http操作完成。nginx lua在不阻止請求的情況下進行外部http調用

如果我使用lua訪問,記錄所花費的時間將被添加到請求時間。

有沒有辦法在異步過程中啓動事件日誌記錄過程,以便請求可以繼續前進,而事件日誌記錄可能需要時間。

+0

嗨,你找到任何真正的解決方案? –

回答

0

我不試試在nginx上。但在我的應用程序中,我使用單獨的線程來執行所有IO並使用ZeroMQ庫與它進行通信。 根據文檔,您可以使用init_by_lua_block中的通信套接字創建/運行工作線程,然後在其他部分使用它。但要做到這一點,你應該記住,如果請求/秒總是大於寫入/秒,那麼最終可能會導致內存不足。另外與ZeromMQ很容易做出幾個工作線程。當然,在這種情況下,工作線程對nginx模塊沒有訪問權限。 但您可以使用例如LuaSocket或Lua-cURL(最後一個可用於在異步模式下執行多個請求)。 單線程基本sceleton。

local thread = function(actor) 
    local msg, err while true do 
    msg, err = actor:recvx() 
    if not msg then break end 
    print(msg) 
    end 
    print('Close thread: ', tostring(err)) 
end 

local zthreads = require "lzmq.threads" 
local ztimer = require "lzmq.timer" 
local actor = zthreads.xactor(thread):start() 

for i = 1, 10 do 
    actor:send(string.format('message #%d', i)) 
    ztimer.sleep(1000) 
end 
0

可以content_by_lua_內做你平常的處理*和明確ngx.eof()

所以HTTP請求將無延遲地處理指定響應輸出流的末尾。

之後,你可以做任何你想要的,使用cosocket API或ngx.location.capture()例如

https://github.com/openresty/lua-nginx-module#ngxeof

下面是從文檔例如:

location = /async { 
    keepalive_timeout 0; 
    content_by_lua_block { 
     ngx.say("got the task!") 
     ngx.eof() -- well written HTTP clients will close the connection at this point 
     -- access MySQL, PostgreSQL, Redis, Memcached, and etc here... 
    } 
} 
+0

謝謝亞歷山大。不幸的是,我沒有提供lua的內容,內容由上游後端提供。任何解決方法? –

+0

爲上游創建一個單獨的位置,並在content_by_lua_ *中使用ngx.location.capture()。它需要更多的編程才能將所有頭文件和主體傳遞迴客戶端,但在正常的請求處理完成時,將允許使用cosocket API或ngx.location.capture()作爲日誌記錄目的。但請記住 - 它是全緩衝解決方案。 –

+0

謝謝,我會試試看。 –

相關問題