在nginx中使用Lua将请求传递给FastCGI

时间:2013-08-21 18:33:30

标签: nginx lua fastcgi

使用使用Lua支持编译的nginx,我们如何对FastCGI处理程序提出一种子请求,就像nginx的fastcgi_pass指令一样?

我想做的是这样的事情:

location = / {
    access_by_lua '
        res = ngx_fastcgi.pass("backend")
    ';
}

(显然,这不起作用。)

我倾注于HttpLuaModule,我看到提及ngx_fastcgingx.location.capture,这显然是

  

对配置的其他位置的非阻塞内部请求   磁盘文件目录或任何其他nginx C模块,如... ngx_fastcgi,   ...

然后按照ngx_fastcgi的链接将我带到HttpFastcgiModule,它只解释了nginx指令,而不是Lua-scriptable命令。 ngx.location.capture是否使用正确的功能? (顺便说一下,这些请求将是localhost,只是在不同的端口,如9000或9001。)

如何在nginx中使用Lua向FastCGI端点转发请求或发出子请求?

1 个答案:

答案 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中构建,还有一些你可能需要或不需要的其他模块。