配置 nginx 发出后台请求

configure nginx to make a background request

我正在构建一个应用程序,我需要在其中对 api-数据组合使用情况进行一些分析。 下面是我的 nginx 配置 -

location /r/ {
    rewrite /r/(.*)$ http://localhost:3000/sample/route1/ redirect;
    post_action /aftersampleroute1/;
}
location /aftersampleroute1/ {
    rewrite /aftersampleroute1/(.*) /stats/;
    proxy_pass http://127.0.0.1:3000;
}

location /r/ 用于将浏览器请求 http://localhost:80/r/quwjDP4us 重定向到 api /sample/route1/quwjDP4us,后者使用 id quwjDP4us 来做某事。 现在在后台我想将 id quwjDP4us 传递给 stats api /stats/quwjDP4us 更新该 id 的数据库记录。

当我启动 nginx 并发出请求时 http://localhost:80/r/quwjDP4us nginx 成功地将我的请求重定向到我的应用程序,但没有在后台向统计信息发出第二个请求 api。我错过了什么?

注意 - post_action 未包含在 nginx 文档中,是否有替代 module/directive 我可以使用?

正如您正确提到的那样,post_action 没有记录并且一直被认为是非官方指令。

Nginx 从 1.13.4 版本开始提供了一个新的 "mirror" 模块,在文档中描述 here。所以我建议你试一试。在你的情况下,它看起来像这样 –

location /r/ {
    rewrite /r/(.*)$ http://localhost:3000/sample/route1/ redirect;
    mirror /stats;
}

location = /stats {
    internal;
    rewrite /sample/route1/(.*) /stats/;
    proxy_pass http://127.0.0.1:3000;
}

这行不通!

我已经构建了一个测试配置,不幸的是这不起作用。它对 rewritereturn 都不起作用。但它适用于 proxy_pass.

为什么

解释如下。在 Nginx 处理期间,一个 HTTP 请求顺序地通过几个 "phases"。问题是 mirrorPRECONNECT 阶段被触发,该阶段晚于 REWRITE 阶段,其中 rewrite/return 结束请求处理。因此,mirror 甚至不会被触发,因为它的处理会在稍后发生。

如果从该位置提供文件或通过 proxy_pass(或 fastcgi_pass 等)进行代理,处理将最终到达 REWRITE 阶段并且 mirror 将被执行。

Nginx 文档中描述了阶段 here

解决方法

我看不出有什么不取舍的好的解决方案。您可以创建一个额外的位置(返回重定向)并代理来自 /r/ 的请求,以便触发 mirror。像这样,取决于您的其余配置:

location /r/ {
  # you may need setting Host to match `server_name` to make sure the
  # request will be caught by this `server`.
  # proxy_set_header Host $server_name;
  proxy_pass http://<ip from listen>:<port from listen>/redirect/;
  mirror /stats;
}

location = /redirect {
  rewrite /redirect(.*)$ http://localhost:3000/sample/route1 redirect;
}

当然这是次优的并且有额外的样板文件。