Назад | Перейти на главную страницу

nginx: напрямую отправлять из местоположения в другое указанное местоположение

В моем nginx 1.12.2 conf у меня есть:

upstream app {
  server unix:/tmp/app.sock  fail_timeout=0;
}

server {
  listen 443 deferred;

  root /some/dir;

  try_files $uri @app;

  # If the request is for the naked domain, just serve the index bundle
  # without going through Rails
  #
  location = / {
    try_files /index.html =404;
  }

  # If the request if for the /api prefix, go directly to Rails.
  # This location block is not strictly required, but it could be a handy
  # customization hook for extra headers and settings.
  #
  location /api/ {
    # Extra conf!
    try_files @app;
  }

  # The location directory allows very creative configurations.
  # http://nginx.org/en/docs/http/ngx_http_core_module.html#location
  #
  # This is just a named location to be used in try_files.
  location @app {
    proxy_pass_request_headers on;
    proxy_set_header ...
    proxy_pass http://app;
  }
}

Там это не совсем правильно, потому что у него есть единственный аргумент:

  location /api/ {
    # Extra conf!
    try_files @app;
  }

... но он хорошо передает то, чего я пытаюсь достичь. Я полагаю, я мог бы получить try_files для работы, добавив перед последним аргументом файл non-esitent.

Является try_files единственный способ сделать это, или есть еще одна идиоматическая директива?

У нас довольно сложная конфигурация Nginx, и мы хотели использовать именованные местоположения, чтобы сохранить немного больше СУХОЙ. Из-за этого требования нам пришлось делать именно то, что вы пытаетесь сделать.

Печально то, что мы не смогли найти прямого способа сделать это, но хорошая новость заключается в том, что вы можете обмануть Nginx с помощью try_files директива без штрафов за производительность, указав первый аргумент на /dev/null:

try_files /dev/null @the_named_location;

Это определенно обходной путь, и обычно я сжигал любой запрос на перенос, содержащий этот взлом, и тщательно объяснял разработчику ужасы несоблюдения стандартов и т.д ... но после того, как вы убедились и приняли эту печальную реальность, он фактически изменил вашу конфигурацию выглядят намного лучше. Действительно лучше!

Мы решили, что этот "прием" является "приемлемым", поскольку он показал значительное улучшение с точки зрения качества кода в целом.

(но иногда от этого все равно болят глаза ...)

Ваша схема не сработает. когда nginx останавливается на финале location блок для обработки запроса, он будет использовать "настройки и заголовки", которые находятся в области, которые могут быть унаследованы от окружающего блока, но не буду включать любые «дополнительные заголовки и настройки» из родственных блоков - независимо от процесса, предпринятого для поиска окончательного location блок. Видеть этот документ для большего.

Если у вас есть общие утверждения, применимые к нескольким местоположениям, вы можете выгрузить их в отдельный файл и включить их там, где это необходимо. Например:

location / {
    try_files $uri @app;
}
location /api/ {
    # Extra conf!
    include my/proxy/conf;
}
location @app {
    include my/proxy/conf;
}

Видеть этот документ для большего.