配置nginx以发出后台请求

时间:2018-10-02 06:32:59

标签: nginx proxy nginx-location nginx-reverse-proxy

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

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

位置/r/用于将浏览器请求http://localhost:80/r/quwjDP4us重定向到api /sample/route1/quwjDP4us,该API使用id quwjDP4us来执行某些操作。 现在在后台,我想将ID quwjDP4us传递给统计api /stats/quwjDP4us,该API会更新该ID的数据库记录。

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

注意-Nginx文档中未包含post_action,我可以使用替代模块/指令吗?

1 个答案:

答案 0 :(得分:0)

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

自文档版本here开始,Nginx从1.13.4版本开始提供了一个新的“镜像”模块。因此,我建议您尝试一下。就您而言,它看起来像这样–

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

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

这行不通!

我已经建立了一个测试配置,但是不幸的是,这无法正常工作。它不适用于rewritereturn。但这适用于proxy_pass

为什么

解释如下。在Nginx中进行处理期间,HTTP请求按顺序传递了几个“阶段”。问题是mirror在阶段PRECONNECT中被触发,而阶段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$1 redirect;
}

当然这不是最佳选择,并且具有额外的样板。