Что находится перед каждым веб-сервисом
Добро пожаловать
Если вы вводите example.com в браузер, вы практически никогда не достигаете машины, которая действительно запускает приложение. Вы достигаете машины, которая перекидывает запрос на ту, что делает. Эта передаточная машина носит имя: реверс-прокси.
Эта лекция teaches, что делает реверс-прокси, почему почти каждый публичный веб-сервис прячется за одним, и что три задачи, которые выполняет слой на границе одновременно.
К концу вы поймете:
- Разницу между клиентом, прокси и источником
- Почему прокси перед исходным источником защищает, масштабируется и позволяет заменять части без того, чтобы кто-то заметил
- Три задачи, которые выполняет реверс-прокси одновременно: прятать источник, завершать TLS и распределять нагрузку между репликами
- Как запрос передвигается от браузера к прокси к верхнему и обратно, шаг за шагом
К концу вы будете уверенно рассуждать о размещении прокси, разделении забот на границе и почему состояние-прокси слоя умножается дешево, в то время как один исходный источник не делает.
Форвард-прокси vs Реверс-прокси
Две направленности прокси
Оба вида прокси стоят между двумя сторонами и передают трафик. Они отличаются стороной, которую представляют.
Форвард-прокси: стоит перед группой клиентов. Клиенты знают о прокси; внешний сервер видит адрес прокси, а не адрес клиента. Корпоративные выходные прокси, фильтры контента и SOCKS-прокси соответствуют этому шаблону.
Реверс-прокси: стоит перед группой серверов. Внешний мир (клиенты) общается с адресом прокси; клиенты не знают, что реальный сервер прячется за ним. almost каждый публичный веб-сервис использует один.
Мнемоническое правило: форвард-прокси прячет клиентов от серверов. Реверс-прокси прячет серверы от клиентов.
Почему важно заботиться о том, в каком направлении? Задача, режимы ошибок и граница безопасности отличаются. Форвард-прокси беспокоится о том, с кем его пользователи обращаются; реверс-прокси беспокоится о том, с кем обращаются к его серверам.
Клиент, отправляющий трафик через оба вида одновременно, проходит: client -> forward_proxy -> интернет -> reverse_proxy -> origin.
Почему Так Много на Кромке
Кромочная Слойка Зарабатывает На Своем
Обратный прокси выполняет три работы одновременно. Каждая из них оправдывает слой; когда все три выполняются под одним адресом, объясняется почему практически вся производственная веб-архитектура имеет один и тот же вид в передней части.
Работа 1: Маскировать исходный источник. Прокси отвечает на публичном IP. Backend расположены на приватных IP, к которым интернет не может получить доступ. Атакующий, который хочет атаковать исходный источник, сначала должен компрометировать прокси.
Работа 2: Завершение TLS. Прокси хранит сертификат для example.com и дешифрирует входящие HTTPS-запросы. Backend обмениваются простым HTTP (или более простым внутренним TLS) с прокси через надежную сегмент сети. Политики обновления сертификатов и сжатия живут в одном месте.
Работа 3: Распределение нагрузки. Прокси выбирает, какой backend обрабатывает каждый запрос. Backend позади одного прокси образуют пул; прокси выбирает один для каждого запроса с использованием стратегии (в цикле, с наименьшим количеством соединений, хэш на заголовке). Добавление мощности означает добавление backend в пул, а не сообщение каждому клиенту о новом адресе.
Каждая работа - это небольшая программа. Вместе они объясняют, почему уровень, такой простой, как 'Caddy перед Python-приложением', несет больше дизайнерской нагрузки, чем само Python-приложение.
Проектирование для Трех Всех
Ваш команда работает с небольшим API на одном Python-процессе, слушающем порт 8000 на одном VM. Трафик стал настолько большим, что одна VM не может справиться, и обзор безопасности указал, что VM имеет публичный IP и хранит свой собственный TLS-сертификат.
Вы решаете вставить обратный прокси вперед. Отрисуйте схему: куда указывает DNS, где хранится сертификат, как нагрузка достигает backend и что меняется в оригинальной VM?
Заменить компонент, не замечая этого
Индиректия дает свободу
Старая пословица из области компьютерных наук гласит: любую проблему можно решить, добавив слой индиректии (кроме проблемы слишком большого количества слоев индиректии). Обратный прокси - один из самых полезных индиректов в распределенных системах.
Что вы даете:
- Заменяемые backend. Переместить приложение с Python на Go? Мигрировать из одного датацентра в другой? Выпустить новую версию с нулевым временем простоя? Каждое происходит позади стабильной публичной адресации. У пользователей ничего не меняется.
- Независимое масштабирование. Тtier прокси масштабируется на основе пропускной способности и CPU на уровне TLS. Backend tier масштабируется на основе работы приложения. Каждый растет на своей оси потому что они живут на разных машинах.
- Изолированная ответственность. Плохая развертка на backend не вырубает публичный адрес. Прокси остается в рабочем состоянии; вы вносите исправления или откатываетесь; мир восстанавливается, когда backend восстанавливается.
- Разнонаправленные задачи в одном месте. Ограничение скорости, блокировка по гео, ведение журналов запросов, изменение заголовков, кэширование, сжатие ответов: все живет на прокси. Код backend остается сосредоточенным на приложении.
Без прокси каждая из этих проблем должна жить внутри процесса приложения. С прокси они живут на одном уровне, который одну команду owns.
Цена: еще один уровень для работы. Опытные команды принимают эту цену потому что tier прокси сам работает без состояния и масштабируется горизонтально; заменить одного прокси на два не требует координации.
Блэк/Грин Развертка через Прокси
Ваша команда работает версию 1 API на трех backend VM (блэк пулинг) позади обратного прокси. Вы хотите развернуть версию 2 с возможностью быстрого откатывания в случае возникновения проблем в течение тридцати секунд.
Вы запускаете три новых backend VM (зеленый пулинг), работающих на версии 2, бок о бок с пулингом блэк, но пока что ни один трафик не направляется к ним.
От Браузера к Бэкенду и Обратно
Следуйте одному Запросу Начиная от Конца
Отслеживайте одиночный HTTPS GET https://api.example.com/users/42 через обратный прокси перед бэкендной пулем.
Хоп 1: Разрешение DNS. Браузер спрашивает резолвер о api.example.com. Резолвер возвращает публичный IP прокси (например, 203.0.113.10). Браузер открывает TCP-соединение с 203.0.113.10:443.
Хоп 2: Рукопожатие TLS. Прокси представляет свой сертификат для api.example.com. Браузер проверяет сертификат, стороны соглашаются с сессионным ключом, и шифрованный канал открывается.
Хоп 3: HTTP-запрос внутри TLS. Браузер отправляет GET /users/42 HTTP/1.1\nHost: api.example.com\n.... Прокси дешифрирует байты запроса.
Хоп 4: Выбор бэкенда. Прокси консультируется с своим пулем бэкендов для api.example.com и выбирает один бэкенд (например, 10.0.0.21:8000) с помощью своей стратегии балансировки нагрузки.
Хоп 5: Внутренний запрос. Прокси открывает (или использует в повторном использовании) обычное HTTP-соединение с 10.0.0.21:8000 и пересылает запрос. Прокси может изменять заголовки во время передачи: добавлять X-Forwarded-For: <client-ip>, устанавливать Host: правильно, удалять заголовки, передаваемые хоп за хоп, такие как Connection.
Хоп 6: Обработка бэкенда. Приложение бэкенда читает запрос, запрашивает базу данных, создает JSON-ответ.
Хоп 7: Внутренний ответ. Бэкенд отправляет ответ обратно в прокси в виде обычного HTTP.
Хоп 8: Крайний ответ. Прокси может изменять или сжимать ответ, шифрировать его обратно через TLS-сессию и отправлять в браузер.
Хоп 9: Жизненный цикл соединения. TLS-сессия обычно остается открыта для следующего запроса (HTTP/2 использует множество запросов на одном соединении). Соединение прокси-бэкенда часто пулится для повторного использования.
Каждый публичный веб-сервис следует некоторой вариации этой формы. Знание хопов позволяет вам разумно рассуждать о местах, где накапливается задержка, где должна быть логика, и где может скрываться ошибка.
Где Ушло Время?
Пользователь жалуется на то, что API кажется медленным. Вы измеряете и обнаруживаете, что запрос занимает 850 мс с начала и до конца. Серверные логи на backend показывают, что приложение обслужило запрос за 40 мс. Логи прокси показывают, что прокси потратило 50 мс на свою работу (TLS handshake + routing + response writing).
Проектирование минимального edge для нового сервиса
Синтез
Вы узнали разницу между forward и reverse proxy, три задачи, которые выполняет reverse proxy одновременно, почему скрытие origins приносит дивиденды каждый раз, когда вам нужно что-то изменить, и как запрос проходит через edge hop by hop.
Теперь примените это.
Малая команда планирует запустить новый сервис под названием notes.example.com. Пользователи будут читать и писать личные заметки. Команда будет запускать два backend VM в момент запуска и ожидает роста до десяти в течение года. Они хотят HTTPS для пользователей, постепенное развертывание новых версий и отсутствие публичного доступа к backend IPs.
Где идут следующие уроки
Где идут следующие уроки
Этот урок закрепил форму слоя edge. В этом курсе еще четыре урока на основе этого:
- Безсостоятельное горизонтальное масштабирование: почему прокси слой (& задние процессы за ним) удваивается дешево, & математика для размера реплик при всплеске.
- Разделение входящего/исходящего трафика: почему в итоге одиночный прокси узел, обрабатывающий как входящий, так и исходящий трафик, терпит неожиданные сбои, & как разделить слои.
- Режимы отказа & радиус взрыва: как одно изменение конфигурации превращается в отключение, & как писать безвинные действия, предотвращающие повторение.
- Наблюдаемость & емкость: что измерять на границе, чтобы узнать, что что-то сломалось, пока пользователи еще об этом не узнают.
Каждая лекция самостоятельна. В совокупности они дают вам рабочую модель в голове о флите на уровне веб-скалы.
Сопутствующая лекция: geometry_of_proxies_and_origins преобразует все из этой лекции в направленный граф & исследует, что графовая теория говорит вам о пути запроса.
Хорошо сделано. Дальше.