Поиск по сайту:

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


Введение

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

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

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

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

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

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

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

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

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

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

Директива proxy_pass в основном используется в контексте местоположения. Это также допустимо в блоках if в контексте местоположения и в контекстах limit_except. Когда запрос соответствует местоположению с директивой proxy_pass внутри, запрос перенаправляется на URL-адрес, заданный директивой.

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

# server context

location /match/here {
    proxy_pass http://example.com;
}

. . .

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

Например, когда запрос /match/here/please обрабатывается этим блоком, URI запроса будет отправлен на сервер example.com как http ://example.com/match/here/please.

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

# server context

location /match/here {
    proxy_pass http://example.com/new/prefix;
}

. . .

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

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

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

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

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

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

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

  • Nginx избавляется от любых пустых заголовков. Нет смысла передавать пустые значения на другой сервер; это только раздует запрос.
  • Nginx по умолчанию считает недействительным любой заголовок, содержащий символы подчеркивания. Это удалит их из проксируемого запроса. Если вы хотите, чтобы Nginx интерпретировал их как действительные, вы можете установить для директивы underscores_in_headers значение \on, иначе ваши заголовки никогда не попадут на внутренний сервер.
  • Заголовок \Host переписывается в значение, определенное переменной $proxy_host. Это будет IP-адрес или имя и номер порта восходящего потока, непосредственно как определено директива proxy_pass.
  • Заголовок \Соединение изменен на \закрыть. Этот заголовок используется для передачи информации о конкретном соединении, установленном между двумя сторонами. В этом случае Nginx устанавливает для этого параметра значение «закрыть», чтобы указать вышестоящему серверу, что это соединение будет закрыто после получения ответа на исходный запрос. Восходящему потоку не следует ожидать, что это соединение будет постоянным.

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

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

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

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

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

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

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

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

# server context

location /match/here {
    proxy_set_header HOST $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_pass http://example.com/new/prefix;
}

. . .

Приведенный выше запрос устанавливает заголовок \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, чтобы на них можно было ссылаться более чем в одном месте:

# server context

proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

location /match/here {
    proxy_pass http://example.com/new/prefix;
}

location /different/match {
    proxy_pass http://example.com;
}

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

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

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

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

# http context

upstream backend_hosts {
    server host1.example.com;
    server host2.example.com;
    server host3.example.com;
}

server {
    listen 80;
    server_name example.com;

    location /proxy-me {
        proxy_pass http://backend_hosts;
    }
}

В приведенном выше примере мы настроили восходящий контекст с именем backend_hosts. После определения это имя будет доступно для использования в прокси-проходах, как если бы оно было обычным доменным именем. Как видите, в нашем блоке сервера мы передаем любой запрос, сделанный на example.com/proxy-me/..., в пул, который мы определили выше. В этом пуле хост выбирается с применением настраиваемого алгоритма. По умолчанию это просто циклический процесс выбора (каждый запрос по очереди направляется на другой хост).

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

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

  • (циклический перебор): алгоритм балансировки нагрузки по умолчанию, который используется, если отсутствуют другие директивы балансировки. Каждому серверу, определенному в вышестоящем контексте, последовательно передаются запросы.
  • least_conn: указывает, что новые подключения всегда должны предоставляться серверной части с наименьшим количеством активных подключений. Это может быть особенно полезно в ситуациях, когда подключение к серверной части может сохраняться в течение некоторого времени.
  • ip_hash: этот алгоритм балансировки распределяет запросы на разные серверы в зависимости от IP-адреса клиента. Первые три октета используются в качестве ключа для выбора сервера для обработки запроса. В результате клиенты, как правило, каждый раз обслуживаются одним и тем же сервером, что может способствовать согласованности сеансов.
  • хеш: этот алгоритм балансировки в основном используется с проксированием memcached. Серверы делятся на основе значения произвольно предоставленного хеш-ключа. Это может быть текст, переменные или их комбинация. Это единственный метод балансировки, который требует от пользователя предоставления данных, которые являются ключом, который следует использовать для хэша.

При смене алгоритма балансировки блок может выглядеть примерно так:

# http context

upstream backend_hosts {

    least_conn;

    server host1.example.com;
    server host2.example.com;
    server host3.example.com;
}

. . .

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

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

# http context

upstream backend_hosts {

    hash $remote_addr$remote_port consistent;

    server host1.example.com;
    server host2.example.com;
    server host3.example.com;
}

. . .

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

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

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

# http context

upstream backend_hosts {
    server host1.example.com weight=3;
    server host2.example.com;
    server host3.example.com;
}

. . .

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

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

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

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

  • Подключение клиента к прокси-серверу Nginx.
  • Подключение прокси-сервера Nginx к внутреннему серверу.

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

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

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

  • proxy_buffering: эта директива определяет, включена ли буферизация для этого контекста и дочерних контекстов. По умолчанию эта функция включена.
  • proxy_buffers: эта директива управляет количеством (первый аргумент) и размером (второй аргумент) буферов для проксируемых ответов. По умолчанию настроено 8 буферов размером, равным одной странице памяти (либо 4k, либо 8k). Увеличение количества буферов может позволить буферизировать больше информации.
  • proxy_buffer_size: начальная часть ответа от внутреннего сервера, содержащая заголовки, буферизуется отдельно от остальной части ответа. Эта директива устанавливает размер буфера для этой части ответа. По умолчанию это будет тот же размер, что и proxy_buffers, но, поскольку он используется для информации заголовка, обычно можно установить меньшее значение.
  • proxy_busy_buffers_size: эта директива устанавливает максимальный размер буферов, которые могут быть помечены как «готовые для клиента» и, следовательно, заняты. Хотя клиент может считывать данные только из одного буфера за раз, буферы помещаются в очередь для отправки клиенту пакетами. Эта директива определяет размер буферного пространства, разрешенного для этого состояния.
  • proxy_max_temp_file_size: максимальный размер временного файла на диске на один запрос. Они создаются, когда исходящий ответ слишком велик, чтобы поместиться в буфер.
  • proxy_temp_file_write_size: это объем данных, который Nginx будет записывать во временный файл за один раз, когда ответ прокси-сервера слишком велик для настроенных буферов.
  • proxy_temp_path: это путь к области на диске, где Nginx должен хранить любые временные файлы, когда ответ вышестоящего сервера не помещается в настроенные буферы.

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

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

# server context

proxy_buffering on;
proxy_buffer_size 1k;
proxy_buffers 24 4k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 32k;

location / {
    proxy_pass http://example.com;
}

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

# server context

proxy_buffering off;
proxy_buffer_size 4k;

location / {
    proxy_pass http://example.com;
}

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

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

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

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

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

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

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

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

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

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

# http context

proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=backcache:8m max_size=50m;
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;

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

sudo mkdir -p /var/lib/nginx/cache
sudo chown www-data /var/lib/nginx/cache
sudo chmod 700 /var/lib/nginx/cache

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

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

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

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

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

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

# server context

location /proxy-me {
    proxy_cache backcache;
    proxy_cache_bypass $http_cache_control;
    add_header X-Proxy-Cache $upstream_cache_status;

    proxy_pass http://backend;
}

. . .

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

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

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

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

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

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

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

  • no-cache: указывает, что ответ не следует обслуживать снова, не проверив предварительно, что данные не изменились на сервере. Это можно использовать, если данные динамичны и важны. Хэшированный заголовок метаданных ETag проверяется при каждом запросе, и предыдущее значение может быть предоставлено, если серверная часть возвращает такое же хеш-значение.
  • no-store: указывает, что полученные данные ни в коем случае не должны кэшироваться. Это самый безопасный вариант для личных данных, так как это означает, что данные должны каждый раз извлекаться с сервера.
  • private: это указывает на то, что никакое пространство общего кэша не должно кэшировать эти данные. Это может быть полезно для указания того, что браузер пользователя может кэшировать данные, но прокси-сервер не должен считать эти данные действительными для последующих запросов.
  • public: это указывает на то, что ответ является общедоступными данными, которые могут быть кэшированы в любой точке соединения.

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

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

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

location / {
    expires 60m;
}

location /check-me {
    expires -1;
}

В приведенном выше примере первый блок позволяет кэшировать содержимое в течение часа. Второй блок устанавливает для заголовка Cache-Control значение \no-cache. Чтобы установить другие значения, вы можете использовать директиву add_header, например:

location /private {
    expires -1;
    add_header Cache-Control "no-store";
}

Заключение

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