使用ngx.location.capture()方法對預定義的位置塊執行子請求。然後,從位置塊內執行外部FastCGI請求。因爲子請求本身實際上並不是網絡操作,而是純粹在基於nginx C的環境中執行的,所以幾乎沒有開銷。此外,因爲FastCGI請求和其他「proxy_pass」類型的請求是基於事件的,所以nginx可以作爲一個有效的中介。
舉個例子,你可以有以下幾點:
location/{
access_by_lua '
response = ngx.location.capture("/my-subrequest-handler")
if response.status == 404 then
return ngx.exit(401) -- can't find/authenticate user, refuse request
end
ngx.say(response.status)
';
# other nginx config stuff here as necessary--perhaps another fastcgi_pass
# depending upon the status code of the response above...
}
location = /my-subrequest-handler {
internal; # this location block can only be seen by nginx subrequests
fastcgi_pass localhost:9000; # or some named "upstream"
fastcgi_pass_request_body off; # send client request body upstream?
fastcgi_pass_request_headers off; # send client request headers upstream?
fastcgi_connect_timeout 100ms; # optional; control backend timeouts
fastcgi_send_timeout 100ms; # same
fastcgi_read_timeout 100ms; # same
fastcgi_keep_conn on; # keep request alive
include fastcgi_params;
}
在上面的例子中,即使我執行子請求「/我 - 子請求處理程序」,實際的URL傳遞給FastCGI進程是HTTP客戶端首先調用nginx請求的進程。
請注意,ngx.location.capture是一個同步但非阻塞的操作,這意味着您的代碼執行會停止,直到收到響應,但nginx工作人員在此期間可以自由執行其他操作。
有一些非常酷的事情,你可以用Lua在nginx管道中的任意位置修改請求和響應。例如,你可以通過更改原始請求,方法是添加標題,刪除標題,甚至轉換正文。也許調用者想要使用XML,但上游應用程序只理解JSON,我們可以在調用上游應用程序時轉換爲/從JSON轉換。
默認情況下,Lua沒有內置到nginx中。相反,它是一個必須編譯進來的第三方模塊。有一種叫做OpenResty的nginx,它可以構建在Lua + LuaJIT中,以及一些其他可能需要或不需要的模塊。
這就是訣竅! – Matt