使用使用Lua支持编译的nginx,我们如何对FastCGI处理程序提出一种子请求,就像nginx的fastcgi_pass
指令一样?
我想做的是这样的事情:
location = / {
access_by_lua '
res = ngx_fastcgi.pass("backend")
';
}
(显然,这不起作用。)
我倾注于HttpLuaModule,我看到提及ngx_fastcgi
和ngx.location.capture
,这显然是
对配置的其他位置的非阻塞内部请求 磁盘文件目录或任何其他nginx C模块,如... ngx_fastcgi, ...
然后按照ngx_fastcgi
的链接将我带到HttpFastcgiModule,它只解释了nginx指令,而不是Lua-scriptable命令。 ngx.location.capture
是否使用正确的功能? (顺便说一下,这些请求将是localhost
,只是在不同的端口,如9000或9001。)
如何在nginx中使用Lua向FastCGI端点转发请求或发出子请求?
答案 0 :(得分:5)
使用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;
}
在上面的例子中,即使我正在对“/ my-subrequest-handler”执行子请求,传递给FastCGI进程的实际URL也是HTTP客户端首先调用nginx所请求的URL。
请注意,ngx.location.capture是一个同步但非阻塞的操作,这意味着您的代码执行会在收到响应之前停止,但nginx worker可以在此期间自由执行其他操作。
您可以使用Lua在nginx管道中的任何位置修改请求和响应。例如,您可以通过添加标题,删除标题,甚至转换正文来更改原始请求。也许调用者想要使用XML,但是上游应用程序只能理解JSON,我们可以在调用上游应用程序时转换为/从JSON转换。
默认情况下,Lua没有内置到nginx中。相反,它是必须编译的第三方模块。有一种叫做OpenResty的nginx,它在Lua + LuaJIT中构建,还有一些你可能需要或不需要的其他模块。