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

Вступление

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

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

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

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

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

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

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

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

. . .

В приведенном выше фрагменте конфигурации в конце сервера в определенииproxy_pass не указан URI. Для определений, которые соответствуют этому шаблону, 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 устанавливает это значение «close», чтобы указать вышестоящему серверу, что это соединение будет закрыто после ответа на исходный запрос. Восходящий поток не должен ожидать, что это соединение будет постоянным.

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

Следующим моментом, который следует почерпнуть из приведенной выше информации, является то, что если ваше внутреннее приложение будет обрабатывать нестандартные заголовки, вы должны убедиться, что в нихdo not есть символы подчеркивания. Если вам нужны заголовки, в которых используется подчеркивание, вы можете установить для директивы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/..., в пул, который мы определили выше. В этом пуле хост выбирается с помощью настраиваемого алгоритма. По умолчанию это простой процесс циклического выбора (каждый запрос будет поочередно направляться на другой хост).

Изменение алгоритма балансировки вверх по течению

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

  • (round robin): алгоритм балансировки нагрузки по умолчанию, который используется, если нет других директив балансировки. Каждый сервер, определенный в восходящем контексте, последовательно получает запросы.

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

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

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

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

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

# 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, сервера или местоположения. Важно помнить, что директивы размера настроеныper request, поэтому их увеличение сверх ваших потребностей может повлиять на вашу производительность при большом количестве клиентских запросов:

  • 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 можно сделать более надежным, добавив избыточный набор балансировщиков нагрузки, создав инфраструктуру высокой доступности.

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

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

HA Setup

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

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

В то время как буферизация может помочь освободить внутренний сервер для обработки большего количества запросов, 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 как «без кеширования». Чтобы установить другие значения, вы можете использовать директивуadd_header, например:

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

Заключение

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

Related