configure nginx to make a background request

荒凉一梦 提交于 2020-01-13 05:58:26

问题


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;
}

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.

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?

Note - post_action is not included in nginx docs, is there an alternate module/directive I can use?


回答1:


As you correctly mentioned, post_action is not documented and has always been considered an unofficial directive.

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;
}

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.

Why

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.

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.

Phases are described in Nginx documentation here.

Workarounds

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.



来源:https://stackoverflow.com/questions/52603090/configure-nginx-to-make-a-background-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!