Понимание Nginx HTTP-прокси, балансировки нагрузки, буферизации и кэширования

Понимание Nginx HTTP-прокси, балансировки нагрузки, буферизации и кэширования Хостинг
Содержание
  1. Введение
  2. Общая информация о проксировании
  3. Деконструкция базового прохода прокси-сервера HTTP
  4. Понимание того, как Nginx обрабатывает заголовки
  5. Установка или сброс заголовков
  6. Определение восходящего контекста для прокси-соединений с балансировкой нагрузки
  7. Изменение алгоритма балансировки восходящего потока
  8. Настройка веса сервера для балансировки
  9. Использование буферов для освобождения внутренних серверов
  10. Высокая доступность (необязательно)
  11. Настройка прокси-кэширования для уменьшения времени отклика
  12. Настройка прокси-кэша
  13. Примечания о кэшировании результатов
  14. Настраиваем Nginx (Revers Proxy)
  15. Заголовки X-Scheme и X-Forwarded-Proto
  16. Заголовки X-Real-PORT и X-Real-IP
  17. Параметры отвечающие за буферную память
  18. Что и куда проксируем
  19. Настраиваем Apache2 (backend сервера)
  20. Проксирование и абсолютные ссылки
  21. Передача запроса на прокси-сервер
  22. Настройка буферов
  23. Выбор исходящего IP-адреса

Введение

В этом руководстве мы обсудим возможности HTTP-прокси Nginx, которые позволяют Nginx передавать запросы на внутренние http-серверы для дальнейшей обработки. Nginx часто настраивается как решение для обратного прокси-сервера, чтобы помочь масштабировать инфраструктуру или передавать запросы на другие серверы, которые не предназначены для обработки больших клиентских нагрузок.

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

Общая информация о проксировании

Если в прошлом вы использовали веб-серверы только для простых конфигураций с одним сервером, вам может быть интересно, зачем вам нужно прокси-запросы.

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

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

Nginx может проксировать запросы к серверам, которые взаимодействуют с использованием протоколов http(s), FastCGI, SCGI и uwsgi или memcached через отдельные наборы директив для каждого типа прокси. В этом руководстве мы сосредоточимся на протоколе http. Экземпляр Nginx отвечает за передачу запроса и преобразование любых компонентов сообщения в формат, который может понять вышестоящий сервер.

Деконструкция базового прохода прокси-сервера HTTP

Самый простой тип прокси-сервера предполагает передачу запроса на один сервер, который может обмениваться данными по протоколу http. Этот тип прокси известен как общий «прокси-проход» и обрабатывается директивой с метким названием proxy_pass.

Давайте рассмотрим пример:

# контекст сервера

. . .

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

Давайте рассмотрим альтернативный сценарий:

В приведенном выше примере прокси-сервер определяется с сегментом URI на конце (/new/prefix). Когда в определении proxy_pass указан URI, часть запроса, соответствующая определению местоположения, заменяется этим URI во время передачи.

Например, запрос /match/here/please на сервере Nginx будет передан вышестоящему серверу как http://example.com/new/prefix/please. Префикс /match/here заменяется префиксом /new/. Это важный момент, о котором следует помнить.

Иногда такая замена невозможна. В этих случаях URI в конце определения proxy_pass игнорируется, и либо исходный URI от клиента, либо URI, измененный другими директивами, будет передан вышестоящему серверу.

Понимание того, как Nginx обрабатывает заголовки

Одна вещь, которая может быть не сразу понятна, заключается в том, что важно передавать больше, чем просто URI, если вы ожидаете, что вышестоящий сервер правильно обработает запрос. Запрос, исходящий от Nginx от имени клиента, будет выглядеть иначе, чем запрос, исходящий непосредственно от клиента. Большая часть этого — заголовки, которые сопровождают запрос.

Когда Nginx проксирует запрос, он автоматически вносит некоторые коррективы в заголовки запросов, которые он получает от клиента:

Первое, что мы можем экстраполировать из вышесказанного, это то, что любой заголовок, который вы не хотите передавать, должен быть установлен в пустую строку. Заголовки с пустыми значениями полностью удаляются из переданного запроса.

Следующий момент, который следует усвоить из приведенной выше информации, заключается в том, что если ваше серверное приложение будет обрабатывать нестандартные заголовки, вы должны убедиться, что они не содержат символов подчеркивания. Если вам нужны заголовки, использующие символ подчеркивания, вы можете установить директиву underscores_in_headers в положение «on» дальше в вашей конфигурации (действительно либо в контексте http, либо в контексте объявления сервера по умолчанию для комбинации IP-адреса/порта). Если вы этого не сделаете, Nginx пометит эти заголовки как недействительные и молча удалит их, прежде чем передать вашему восходящему потоку.

Заголовок «Host» имеет особое значение в большинстве сценариев проксирования. Как указано выше, по умолчанию для этого будет установлено значение $proxy_host, переменной, которая будет содержать доменное имя или IP-адрес и порт, взятые непосредственно из определения proxy_pass. Это выбрано по умолчанию, поскольку это единственный адрес, на который Nginx может быть уверен, что восходящий сервер ответит (поскольку он извлекается непосредственно из информации о соединении).

Ниже приведены наиболее распространенные значения заголовка «Host»:

В большинстве случаев вы захотите установить заголовок «Host» в переменную $host. Он является наиболее гибким и обычно предоставляет проксируемым серверам максимально точно заполненный заголовок «Host».

Установка или сброс заголовков

Чтобы настроить или установить заголовки для прокси-соединений, мы можем использовать директиву proxy_set_header. Например, чтобы изменить заголовок «Host», как мы обсуждали, и добавить некоторые дополнительные заголовки, общие с проксируемыми запросами, мы могли бы использовать что-то вроде этого:

# контекст сервера

ХОЗЯИН
X-Forwarded-Proto
X-Real-IP
X-переадресовано-для

. . .

Приведенный выше запрос устанавливает заголовок «Host» в переменную $host, которая должна содержать информацию об исходном запрашиваемом хосте. Заголовок X-Forwarded-Proto предоставляет проксируемому серверу информацию о схеме исходного запроса клиента (будь то запрос http или https).

X-Real-IP устанавливается на IP-адрес клиента, чтобы прокси-сервер мог правильно принимать решения или вести журнал на основе этой информации. Заголовок X-Forwarded-For представляет собой список, содержащий IP-адреса всех серверов, через которые клиент был проксирован до этого момента. В приведенном выше примере мы установили это значение в переменную $proxy_add_x_forwarded_for. Эта переменная принимает значение исходного заголовка X-Forwarded-For, полученного от клиента, и добавляет в конец IP-адрес сервера Nginx.

Конечно, мы могли бы переместить директивы proxy_set_header на сервер или в контекст http, чтобы на них можно было ссылаться более чем в одном месте:

# контекст сервера

Читайте также:  Овладейте искусством SEO для своего сайта MySQL на локальном хосте: проверенные методы и инструменты

ХОЗЯИН
X-Forwarded-Proto
X-Real-IP
X-Forwarded-For

Определение восходящего контекста для прокси-соединений с балансировкой нагрузки

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

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

Давайте рассмотрим простой пример:

# контекст http

Изменение алгоритма балансировки восходящего потока

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

# контекст http

. . .

В приведенном выше примере сервер будет выбран на основе того, какой из них имеет наименьшее количество подключений. Директива ip_hash может быть установлена ​​таким же образом, чтобы получить определенную степень «липкости» сеанса.

Что касается метода хеширования, вы должны предоставить ключ для хеширования. Это может быть что угодно:

# контекст http

последовательный

. . .

В приведенном выше примере запросы распределяются на основе значения IP-адреса и порта клиента. Мы также добавили необязательный параметр, который реализует алгоритм согласованного хеширования ketama. По сути, это означает, что если ваши вышестоящие серверы изменятся, это окажет минимальное влияние на ваш кеш.

Настройка веса сервера для балансировки

В объявлениях внутренних серверов по умолчанию все серверы одинаково «взвешены». Это предполагает, что каждый сервер может и должен обрабатывать одинаковую нагрузку (с учетом эффектов алгоритмов балансировки). Однако вы также можете установить альтернативный вес серверам во время объявления:

# контекст http

host1.example.com вес=3

. . .

В приведенном выше примере host1.example.com будет получать в три раза больше трафика, чем два других сервера. По умолчанию каждому серверу назначается вес, равный единице.

Использование буферов для освобождения внутренних серверов

При проксировании на другой сервер скорость двух разных соединений будет влиять на работу клиента:

Nginx может настраивать свое поведение в зависимости от того, какое из этих подключений вы хотите оптимизировать.

Без буферов данные отправляются с проксируемого сервера и сразу начинают передаваться клиенту. Если предполагается, что клиенты работают быстро, буферизацию можно отключить, чтобы данные доходили до клиента как можно быстрее. С буферами прокси-сервер Nginx временно сохраняет ответ бэкэнда, а затем передает эти данные клиенту. Если клиент работает медленно, это позволяет серверу Nginx быстрее закрыть соединение с серверной частью. Затем он может обрабатывать передачу данных клиенту с любой возможной скоростью.

Как видите, Nginx предоставляет довольно много разных директив для настройки поведения буферизации. В большинстве случаев вам не придется беспокоиться о большинстве из них, но может быть полезно настроить некоторые из этих значений. Вероятно, наиболее полезными для настройки являются директивы proxy_buffers и proxy_buffer_size.

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

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

Высокая доступность (необязательно)

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

Настройка высокой доступности (HA) — это инфраструктура без единой точки отказа, и балансировщики нагрузки являются частью этой конфигурации. Имея более одного балансировщика нагрузки, вы предотвращаете потенциальное время простоя, если ваш балансировщик нагрузки недоступен или вам нужно отключить его для обслуживания.

Вот схема базовой настройки высокой доступности:

Настройка прокси-кэширования для уменьшения времени отклика

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

Настройка прокси-кэша

Чтобы настроить кеш для проксируемого контента, мы можем использовать директиву proxy_cache_path. Это создаст область, в которой могут храниться данные, возвращаемые с проксируемых серверов. Директива proxy_cache_path должна быть установлена ​​в контексте http.

В приведенном ниже примере мы настроим эту и некоторые связанные директивы для настройки нашей системы кэширования.

# контекст http

/var/lib/nginx/cache level=1:2 keys_zone=backcache:8m max_size=50m

С помощью директивы proxy_cache_path мы определили каталог в файловой системе, где мы хотели бы хранить наш кеш. В этом примере мы выбрали каталог /var/lib/nginx/cache. Если этот каталог не существует, вы можете создать его с правильным разрешением и владельцем, набрав:

sudo mkdir -p /var/lib/nginx/cache
sudo chown www-данные /var/lib/nginx/cache
sudo chmod 700 /var/lib/nginx/cache

Параметр level= указывает, как будет организован кеш. Nginx создаст ключ кэша, хэшируя значение ключа (настроено ниже). Уровни, которые мы выбрали выше, определяют, что будет создана односимвольная директория (это будет последний символ хешированного значения) с двухсимвольной поддиректорией (взятой из следующих двух символов с конца хэш-значения). Обычно вам не нужно беспокоиться об этом, но это помогает Nginx быстро находить нужные значения.

Параметр keys_zone= определяет имя для этой зоны кэша, которую мы назвали backcache. Здесь же мы определяем, сколько метаданных хранить. В данном случае мы храним 8 МБ ключей. На каждый мегабайт Nginx может хранить около 8000 записей. Параметр max_size устанавливает максимальный размер фактических кэшированных данных.

Другая директива, которую мы использовали выше, это proxy_cache_key. Это используется для установки ключа, который будет использоваться для хранения кэшированных значений. Этот же ключ используется для проверки возможности обслуживания запроса из кэша. Мы устанавливаем это на комбинацию схемы (http или https), метода HTTP-запроса, а также запрошенного хоста и URI.

Директиву proxy_cache_valid можно указывать несколько раз. Это позволяет нам настроить, как долго хранить значения в зависимости от кода состояния. В нашем примере мы сохраняем успехи и перенаправления в течение 10 минут, а кеш истекает для 404 ответов каждую минуту.

Теперь мы настроили зону кеша, но нам все еще нужно сообщить Nginx, когда использовать кеш.

В местах, где мы проксируем серверную часть, мы можем настроить использование этого кеша:

# контекст сервера

X-прокси-кэш

. . .

Используя директиву proxy_cache, мы можем указать, что для этого контекста следует использовать зону кэширования обратного кэша. Nginx проверит здесь действительную запись, прежде чем перейти к серверной части.

Директива proxy_cache_bypass установлена ​​в переменную $http_cache_control. Он будет содержать индикатор того, запрашивает ли клиент явно свежую некэшированную версию ресурса. Установка этой директивы позволяет Nginx правильно обрабатывать клиентские запросы такого типа. Дальнейшая настройка не требуется.

Читайте также:  Решение проблем с сетевым подключением в CentOS 7: быстро подключайтесь к Интернету

Мы также добавили дополнительный заголовок X-Proxy-Cache. Мы устанавливаем этот заголовок в значение переменной $upstream_cache_status. По сути, это устанавливает заголовок, который позволяет нам увидеть, привел ли запрос к попаданию в кеш, к промаху или кеш был явно обойден. Это особенно ценно для отладки, но также является полезной информацией для клиента.

Примечания о кэшировании результатов

Кэширование может значительно повысить производительность вашего прокси. Тем не менее, есть определенные соображения, которые следует учитывать при настройке кэша.

Если на вашем сайте есть динамические элементы, вам придется учитывать это на внутренних серверах. Как вы справляетесь с этим, зависит от того, какое приложение или сервер обрабатывает внутреннюю обработку. Для частного контента вы должны установить для заголовка Cache-Control значение «no-cache», «no-store» или «private» в зависимости от характера данных:

Соответствующий заголовок, который может управлять этим поведением, — это заголовок max-age, который указывает количество секунд, в течение которых любой ресурс должен кэшироваться.

Правильная установка этих заголовков, в зависимости от конфиденциальности содержимого, поможет вам воспользоваться кэшем, сохраняя при этом безопасность ваших личных данных и свежесть динамических данных.

Если ваш сервер также использует Nginx, вы можете установить некоторые из них с помощью директивы expires, которая установит максимальный возраст для Cache-Control:

Разберём, что такое Reverse Proxy. А также я покажу, как настроить Nginx в качестве Reverse Proxy (обратного прокси-сервера).

Иногда бывает необходимо, чтобы различные запросы URL-адресов обрабатывались на разных серверах, но встречались на одном сервере. Например, вы пробросили порт на свой компьютер на один веб-сервер в вашей внутренней сети. Но хотите, чтобы каталог /xxx открывался на втором веб-сервере, а /yyy открывался на первом, и не хотите просматривать порты на каждом веб-сервере. Получается вот такая схема:

Понимание Nginx HTTP-прокси, балансировки нагрузки, буферизации и кэширования

Nginx — Обратный прокси

То, что мы хотим сделать из сервера web1, называется обратный прокси (обратный прокси).

В то время как прямой прокси-сервер (прямой прокси) работает от имени клиентов, то есть нам необходимо напрягаться (клиент), чтобы тот ходил через прямой прокси-сервер. Обратные же прокси работают от имени серверов, то есть клиент не знает, что он привлекает на прокси-сервер.

Клиенты обратного прокси-сервера берут запросы для того, чтобы проксировать их на проксируемый веб-сервер (как показано на рисунке).

В качестве обратного прокси-сервера для веб-серверов может выступать apace или nginx. Есть и другие решения, но в этой статье разберёмся с nginx. На официальном сайте nginx есть небольшой раздел, посвящённый обратному прокси.

Я буду использовать операционную систему Devuan, это облегченный вариант Debian без systemd. Про установку Devuan я уже писал здесь.

У нас будет три сервера:

Настраиваем Nginx (Revers Proxy)

Устанавливаем nginx на сервере proxy:

# apt install -y nginx

У меня установился nginx такой версией:

# nginx -v
nginx version: nginx/1.14.2

Для настройки прокси создадим новый виртуальный хост:

После чего отключим конфиг «default«, включим созданный нами конфиг «proxy» и перезагрузим службу сервера:

# rm /etc/nginx/sites-enabled/default
# ln -s /etc/nginx/sites-available/proxy /etc/nginx/sites-enabled/proxy
# service nginx restart

На основных настройках я не буду заострять внимание, потому как они не относятся к настройке reverse proxy. Если вкратце там мы указали какие порты слушает наш сервер, корень сайта, индексные страницы и имя сервера.

Далее рассмотрим те опции, которые относятся к самому проксированию.

Заголовки X-Scheme и X-Forwarded-Proto

При проксировании мы можем менять заголовки, чтобы backend сервер правильно обрабатывал запросы.

Вначале нужно поменять схему и протокол в запросе, если у вас backend сервер работает на одном протоколе (например http), а к proxy подключаются по другому протоколу (например https). То-есть в заголовках X-Scheme и X-Forwarded-Proto нужно указать протокол подключения к backend серверу.

Схема и протокол это разные понятия. То что вы пишите в браузере (http или https) — это схема. А уже схема указывает браузеру по какому протоколу подключаться к серверу.

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

proxy_set_header X-Scheme http;
proxy_set_header X-Forwarded-Proto http;

Заголовок host, один из самых важных заголовков. Он определяет адрес домена, который запрашивает браузер. Сервер, получив запрос, ищет у себя сайт с доменом из заголовка host, а также указанную страницу.

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

В конфиге мы указали следующее:

proxy_set_header Host $http_host;

Заголовок X-Forwarded-For содержит список прокси серверов по которым прошёлся клиент перед этим сервером, а переменная $proxy_add_x_forwarded_for содержит полученный заголовок X-Forwarder-For плюс добавляет свой сервер в этот список (это используется для передачи реального ip-клиента на backend).

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Заголовки X-Real-PORT и X-Real-IP

Эти заголовки содержать содержат ip адрес и порт с которого подключается клиент. Чтобы передать эти значения backend серверу, мы указали следующие параметры:

proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Real-IP $remote_addr;

Параметры отвечающие за буферную память

А следующие строки отвечают за настройку работы буферной памяти для проксируемой информации:

proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 8 8k;

Что и куда проксируем

Теперь разберем часть конфига, где мы указываем что проксировать и куда проксировать:

Настраиваем Apache2 (backend сервера)

На обоих серверах проделаем одно и тоже! Во-первых установим apache2, затем создадим новый каталог /var/www/html/test. В этом каталоге сделаем индексную страничку index.html в которую запишем html код. Вдобавок поменяем владельца нового каталога на www-data.

Проделываем следующее на обоих серверах:

Используя адрес прокси сервера, откроем xxx:

Используя адрес прокси сервера, откроем yyy:

Как видим у нас открылись разные странички, которые лежат на разных серверах!

Теперь сделаем так, чтобы один и тот же запрос ходил по следующим правилам:

Для этого поправим наш конфиг /etc/nginx/sites-enabled/proxy и перед блоком server добавим блок upstream:

В этом блоке указываем оба web-сервера. При этом web1 будет основным сервером. Но если proxy в течении 120 секунд получит три ошибки при обращении к web1, то на 120 секунд все запросы пойдут на web2.

Ниже в блоке server, где мы указывали что на что проксировать (блоки location), поменяем записи. Вместо web1 укажем название апстрима, которое мы придумали выше (backend). Второй блок (location /yyy) — удаляем. Получится так:

Полностью конфиг будет выглядеть так:

В браузере, используя адрес прокси сервера, открываем /xxx:

Запрос xxx идет на web1

Затем отключаем сервер web1 и обновляем страничку:

Запрос xxx идет на web2

Как видим мы перешли на второй сервер. Теперь включим обратно web1 и обновим страничку еще раз:

Теперь мы вернулись на первый сервер.

Таким образом вы можете создать два одинаковых веб сайта и в случае неисправности первого сервера, ваш сайт продолжит работать на втором сервере. Клиенты могут даже ничего не заметить.

Читайте также:  Раскрытие возможностей Oracle Java: улучшите свои навыки программирования

Проксирование и абсолютные ссылки

Теперь приведу одну проблему revers proxy серверов — абсолютные ссылки. Пусть наш сайт (на сервере web1) будет содержать ссылку на некоторую свою страничку. Создадим каталог и в нём новую страничку:

Там же поправим индексную страничку и добавим в неё ссылку:

Обратите внимание, ссылка не относительная, а абсолютная. То-есть начинается с корня сайта.

Откроем web1 напрямую и проверим работу ссылки:


Понимание Nginx HTTP-прокси, балансировки нагрузки, буферизации и кэширования

Проверка работы перехода по ссылки на web1

Как видим, при нажатии на ссылку мы переходим по адресу http://web1/test/test/test.html. И у нас всё работает!

Теперь проверим работу на proxy:


Понимание Nginx HTTP-прокси, балансировки нагрузки, буферизации и кэширования

Проверка работы перехода по ссылки на proxy

На proxy ссылка не работает. Обратите внимание, на каталог к которому мы пытаемся подключиться /test/test/test.html. А у нас на proxy есть только /xxx, который проксируется на /test. А самого /test нет, вот поэтому мы получили ошибку.

Для того, чтобы решить это, нужно на proxy придумывать одноимённые пути для проксирования. Для этого на proxy отредактируйте конфиг:

Проверим работу ссылки на proxy ещё раз:


Понимание Nginx HTTP-прокси, балансировки нагрузки, буферизации и кэширования

Вообще проксирование не простая тема.

Например, проксировать можно https на http или наоборот, но при этом могут возникать проблемы, так как приложение работающее на backend сервере может генерировать ссылки основываясь на схеме. Получается вы к прокси подключаетесь по https, передаёте на backend в заголовке схему http. Затем backend отвечает на http, и приложение генерирует другие ссылки на http и ваш браузер перескакивает на работу по http к proxy, а он допустим умеет только https (и редирект на https не настроен). Получается вот такая картина:


Понимание Nginx HTTP-прокси, балансировки нагрузки, буферизации и кэширования

Проблема проксирования, когда proxy и backend работают на разных протоколах

Поэтому, в идеале, нужно чтобы Revers Proxy работал на том же протоколе, что и Backend сервер.

Или проблема может быть ещё хуже. Ссылки на Backend сервере абсолютные и помимо пути содержат адрес сервера, например такие: http://backend/test/ . Это приведёт к тому, что нажав на ссылку вы перескочите с Proxy сервера к Backend серверу, а он может быть напрямую и недоступен.

Поэтому revers proxy делают в основном к своим внутренним сервисам, которые тоже контролируются. А не на внешние сайты. Которые могут и не уметь работать через revers proxy. Для этой задачи применяют forward proxy, например Squid.

Здесь я разобрал многое, но не всё. Например, можно настроить не резервирование, а балансировку. Про неё, кстати, статей в интернете больше чем про резервный сервер. Я постарался использовать многие http заголовки, чтобы показать как их можно изменять при проксировании. Возможно не все заголовки вам будут нужны в реальной конфигурации. Это зависит от web-приложения, которое вы используете. Буфер для прокси сервера тоже нужно настраивать под конкретную задачу. Поэтому просто копировать приведённые выше конфиги не желательно, нужно анализировать свои действия и все перепроверять.


Понимание Nginx HTTP-прокси, балансировки нагрузки, буферизации и кэширования

Nginx. Reverse Proxy

Configure NGINX as a reverse proxy for HTTP and other protocols, with support for modifying request headers and fine-tuned buffering of responses.

This article describes the basic configuration of a proxy server. You will learn how to pass a request from NGINX to proxied servers over different protocols, modify client request headers that are sent to the proxied server, and configure buffering of responses coming from the proxied servers.

Proxying is typically used to distribute the load among several servers, seamlessly show content from different websites, or pass requests for processing to application servers over protocols other than HTTP.

Передача запроса на прокси-сервер

Когда NGINX проксирует запрос, он отправляет запрос на указанный проксируемый сервер, получает ответ и отправляет его обратно клиенту. Можно передавать запросы HTTP-серверу (другому серверу NGINX или любому другому серверу) или не-HTTP-серверу (который может запускать приложение, разработанное с использованием определенной среды, такой как PHP или Python), используя указанный протокол. Поддерживаемые протоколы включают FastCGI, uwsgi, SCGI и memcached.

Чтобы передать запрос на HTTP-прокси-сервер, директива proxy_pass указывается внутри местоположения. Например:

Этот пример конфигурации приводит к передаче всех запросов, обработанных в этом месте, на прокси-сервер по указанному адресу. Этот адрес может быть указан как доменное имя или IP-адрес. Адрес может также включать порт:

Чтобы передать запрос на прокси-сервер без HTTP, следует использовать соответствующую директиву **_pass:

Директива proxy_pass также может указывать на именованную группу серверов. В этом случае запросы распределяются между серверами в группе по заданному методу.

По умолчанию NGINX переопределяет два поля заголовков в проксируемых запросах, «Хост» и «Соединение», и исключает поля заголовков, значения которых являются пустыми строками. «Host» устанавливается в переменную $proxy_host, а «Connection» устанавливается на закрытие.

В этой конфигурации в поле «Host» установлена ​​переменная $host.

Настройка буферов

По умолчанию NGINX буферизует ответы от проксируемых серверов. Ответ сохраняется во внутренних буферах и не отправляется клиенту до тех пор, пока не будет получен весь ответ. Буферизация помогает оптимизировать производительность при работе с медленными клиентами, которые могут тратить время проксируемого сервера, если ответ передается от NGINX клиенту синхронно. Однако, когда буферизация включена, NGINX позволяет проксируемому серверу быстро обрабатывать ответы, в то время как NGINX хранит ответы столько времени, сколько необходимо клиентам для их загрузки.

За включение и выключение буферизации отвечает директива proxy_buffering. По умолчанию он включен и включена буферизация.

Директива proxy_buffers управляет размером и количеством буферов, выделяемых для запроса. Первая часть ответа от проксируемого сервера хранится в отдельном буфере, размер которого задается директивой proxy_buffer_size. Эта часть обычно содержит сравнительно небольшой заголовок ответа и может быть меньше, чем буферы для остальной части ответа.

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

В этом случае NGINX использует только буфер, настроенный параметром proxy_buffer_size, для хранения текущей части ответа.

Обычно обратный прокси-сервер используется для балансировки нагрузки. Узнайте, как повысить мощность, производительность и сосредоточиться на своих приложениях с помощью быстрого развертывания, из бесплатной электронной книги «Пять причин выбрать программный балансировщик нагрузки».

Выбор исходящего IP-адреса

Если ваш прокси-сервер имеет несколько сетевых интерфейсов, иногда вам может потребоваться выбрать конкретный исходный IP-адрес для подключения к прокси-серверу или вышестоящему серверу. Это может быть полезно, если прокси-сервер за NGINX настроен на прием соединений из определенных IP-сетей или диапазонов IP-адресов.

Оцените статью
Хостинги