1

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

我想做的是这样的:

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

(显然,这不起作用。)

我在HttpLuaModule上看到提到ngx_fastcgiand ngx.location.capture,这显然使

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

但随后按照链接ngx_fastcgi将我带到HttpFastcgiModule,它只解释 nginx 指令,而不是 Lua 可编写脚本的命令。ngx.location.capture使用正确的功能吗?(顺便说一下,这些请求将是 to localhost,只是在不同的端口上,例如 9000 或 9001。)

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

4

1 回答 1

5

使用 ngx.location.capture() 方法对预定义的位置块执行子请求。然后,从 location 块中,执行外部的 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 工作人员在此期间可以自由地执行其他操作。

你可以用 Lua 做一些很酷的事情来修改 nginx 管道中的任何点的请求和响应。例如,您可以通过添加标头、删除标头甚至转换正文来更改原始请求。也许调用者想使用 XML,但上游应用程序只理解 JSON,我们可以在调用上游应用程序时转换为 JSON 或从 JSON 转换。

Lua 默认没有内置在 nginx 中。相反,它是一个必须编译的第 3 方模块。有一种称为OpenResty的 nginx ,它构建在 Lua+LuaJIT 以及一些您可能需要或可能不需要的其他模块中。

于 2013-08-22T18:18:32.607 回答