配置nginx以发出后台请求 [英] configure nginx to make a background request
问题描述
我正在构建一个需要对api数据组合使用情况进行一些分析的应用程序. 以下是我的Nginx配置-
I am building an application where I need to do some analytics on the api-data combination usage. Below is my nginx configuration -
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
传递给stats api /stats/quwjDP4us
,该api会更新该ID的数据库记录.
location /r/
is used to redirect the browser request http://localhost:80/r/quwjDP4us
to api /sample/route1/quwjDP4us
which uses the id quwjDP4us
to do something.
Now in the background I want to pass the id quwjDP4us
to an stats api /stats/quwjDP4us
which updates the db record for that id.
当我启动nginx并发出请求时,http://localhost:80/r/quwjDP4us
nginx成功将我的请求重定向到我的应用程序,但没有在后台向stats api发出第二个请求.我想念什么?
When I start nginx and make the request http://localhost:80/r/quwjDP4us
nginx successfully redirects my request to my application but doesn't make the 2nd request in the background to the stats api. What am I missing?
注意-Nginx文档中未包含post_action
,我可以使用替代模块/指令吗?
Note - post_action
is not included in nginx docs, is there an alternate module/directive I can use?
推荐答案
正如您正确提到的,post_action
没有记录,并且一直被认为是非官方的指令.
As you correctly mentioned, post_action
is not documented and has always been considered an unofficial directive.
Nginx从1.13.4版本开始提供了一个新的镜像"模块,在此处在文档中.因此,我建议您尝试一下.就您而言,它看起来像这样–
Nginx provides a new "mirror" module since version 1.13.4, described here in the documentation. So I advise you to give it a try. In your case, it would look like this –
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;
}
这行不通!
我已经建立了一个测试配置,但是不幸的是,这无法正常工作.它不适用于rewrite
和return
.但它适用于proxy_pass
.
This will not work!
I've built a test configuration and unfortunately this will not work. It works for neither rewrite
nor return
. But it works for proxy_pass
.
解释如下.在Nginx中进行处理期间,HTTP请求按顺序传递了几个阶段".事实是mirror
在阶段PRECONNECT
中被触发,该阶段发生在阶段rewrite
/return
结束请求处理的阶段REWRITE
之后.因此,mirror
甚至都不会被触发,因为它的处理将在以后发生.
The explanation follows. A HTTP request sequentially passes few "phases" during processing in Nginx. The thing is that mirror
gets triggered in phase PRECONNECT
which occurs later than phase REWRITE
where rewrite
/return
end request processing. So, mirror
does not even get triggered because its processing would happen later.
如果从位置提供文件或通过proxy_pass
(或fastcgi_pass
等)进行代理,则处理将最终进入REWRITE
阶段并执行mirror
.
In case of serving files from the location or proxying via proxy_pass
(or fastcgi_pass
, etc), the processing will finally reach REWRITE
phase and mirror
will be executed.
Nginx文档的此处中介绍了各个阶段.
Phases are described in Nginx documentation here.
如果没有取舍,我看不出任何好的解决方案.您可以创建一个额外的位置(返回重定向)并代理来自/r/
的请求,以便触发mirror
.像这样,取决于您的其余配置:
I do not see any good solution without trade-offs. You could create an extra location (returning a redirect) and proxy your request from /r/
, so that mirror
gets triggered. Something like this, depending on the rest of your configuration:
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;
}
当然,这不是最佳选择,并且具有额外的样板.
Certainly this is suboptimal and has extra boilerplate.
这篇关于配置nginx以发出后台请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!