Обслуживание нескольких конечных точек прокси в Nginx


13

У меня есть пара конечных точек API, которые я хочу обслуживать из-под одного местоположения /apiс подпутями, идущими к различным конечным точкам. В частности, я хочу, чтобы webdis был доступен по адресу, /apiа проприетарный API доступен по адресу /api/mypath.

Меня не беспокоит конфликт с API webdis, потому что я использую подпути, которые вряд ли конфликтуют с именами команд redis, а также имею полный контроль над дизайном API, чтобы избежать конфликтов.

Вот файл конфигурации с моего тестового сервера, который я взломал:

server {
  listen 80;
  server_name localhost;
  server_name 192.168.3.90;
  server_name 127.0.0.1;

  location / {
    root /home/me/src/phoenix/ui;
    index index.html;
  }

  # temporary hardcoded workaround
  location = /api/mypath/about {
    proxy_pass http://localhost:3936/v1/about;
  }

  location /api {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://localhost:7379/;
  }

  # tried this but it gives "not found" error
  #location ^~ /api/mypath/ {
  #  rewrite ^/api/mypath/(.*)$ /$1 break;
  #  proxy_pass http://localhost:3936/v1/;
  #}
  #
  #location ^~ /api {
  #  rewrite ^/api/(.*)$ /$1 break;
  #  proxy_pass http://localhost:7379/;
  #}
}

Как я могу изменить мой обходной путь, чтобы любые запросы к /api/mypath/*отправлялись на конечную точку на порту 3936, а все остальное на порт 7379?


Что вы имеете в виду tried this to no avail? Что произошло, когда вы включили эту директиву местоположения? Время соединения вышло? Место не соответствует?
— masegaloeh

Ах, спасибо за подсказку, он выдает не найденную ошибку, при дальнейшем исследовании выясняется, что ошибка исходит от моего API, поэтому он работает! : D Но правило переписывания явно не потому, что я должен добавить v1 к URL ( localhost / api / mypath / v1 / about ) ... :(
— hamstar

Ответы:


24

Вам не нужно переписывать для этого.

server {
  ...

  location ^~ /api/ {
    proxy_pass http://localhost:7379/;
  }
  location ^~ /api/mypath/ {
    proxy_pass http://localhost:3936/v1/;
  }
}

Согласно документации nginx

Местоположение может быть определено строкой префикса или регулярным выражением. Регулярные выражения задаются с помощью предыдущего ~*модификатора (для сопоставления без учета регистра) или ~модификатора (для сопоставления с учетом регистра). Чтобы найти местоположение, соответствующее заданному запросу, nginx сначала проверяет местоположения, определенные с использованием строк префикса (местоположения префикса). Среди них местоположение с самым длинным совпадающим префиксом выбирается и запоминается. Затем проверяются регулярные выражения в порядке их появления в файле конфигурации. Поиск регулярных выражений заканчивается при первом совпадении, и используется соответствующая конфигурация. Если совпадения с регулярным выражением не найдено, используется конфигурация расположения префикса, запомненного ранее.

Если самое длинное совпадающее местоположение префикса имеет ^~модификатор, то регулярные выражения не проверяются.

Поэтому любой запрос, который начинается с /api/mypath/, всегда будет обслуживаться вторым блоком, так как это самый длинный совпадающий префикс.

Любой запрос, который начинается /api/не сразу после него, mypath/всегда будет обслуживаться первым блоком, поскольку второй блок не совпадает, поэтому первый блок становится самым длинным совпадающим местоположением префикса.


2
Если посмотреть на модификаторы местоположения ( =, ~*, ~и ^~) может показаться нелогичным , что ^~исключает регулярные выражения (так как ~указывает на соответствие регулярному выражению) ... Однако, если вы помните, ^внутри класса символов регулярных выражений (например [^a-z]) отрицает , что class (такой, что означает в примере (любой символ, кроме символов из az); аналогично, ^~отменяет любые потенциальные блоки местоположения регулярного выражения.
— Doktor J

6

Хорошо, понял, я думал, что «not found» ошибка исходит от nginx, но на самом деле это было из моего API. Это мое решение, если кому-то интересно:

server {
  listen 80;
  server_name localhost;
  server_name 192.168.3.90;
  server_name 127.0.0.1;

  location / {
    root /home/me/src/phoenix/ui;
    index index.html;
  }

  # automatically go to v1 of the (grape) API
  location ^~ /api/mypath/ {
    rewrite ^/api/mypath/(.*)$ /v1/$1 break;
    proxy_pass http://localhost:3936/;
  }

  location ^~ /api {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://localhost:7379/;
  }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.