English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

гість
1 / ?
назад до уроків

Що стоїть перед майже кожним веб-сервісом

Вітаємо

Якщо ви введете example.com у браузер, ви майже ніколи не потрапляєте на той комп'ютер, який фактично запускає застосунок. Ви потрапляєте на комп'ютер, який передає запит на той, що його обробляє. Цей комп'ютер, що передає запити, має назву: зворотний проксі.

У цьому уроці ви дізнаєтеся, що робить зворотний проксі, чому майже кожен публічний веб-сервіс ховається за ним та які три функції виконує шар на межі одночасно.

До кінця уроку ви зрозумієте:

- Різниця між клієнтом, проксі та оригіналом

- Чому проксі перед оригіналом захищає, масштабується та дозволяє замінювати компоненти без знання користувачів

- Три завдання, які одночасно виконує реверсний проксі: приховування оригіналу, термінування TLS та розподіл навантаження між репліками

- Як запит подорожує від браузера до проксі, потім до upstream-сервера та назад, крок за кроком

До кінця уроку ви зможете впевнено міркувати про розміщення проксі, розділення відповідальності на межі системи та про те, чому безстанова проксі-шар легко масштабується, тоді як єдиний оригінал — ні.

Прямий проксі проти реверсного проксі

Два напрямки проксі

Обидва типи проксі стоять між двома сторонами та ретранслюють трафік. Вони відрізняються тим, яку сторону вони представляють.

Проміжний проксі-сервер (Forward proxy): стоїть перед групою клієнтів. Клієнти знають про наявність проксі; зовнішній сервер бачить адресу проксі, а не адресу клієнта. Корпоративні проксі для вихідного трафіку, фільтри контенту та SOCKS-проксі відповідають цій моделі.

Зворотний проксі-сервер (Reverse proxy): стоїть перед групою серверів. Зовнішній світ (клієнти) спілкується з адресою проксі; клієнти не мають уявлення про те, що за ним ховається реальний сервер. Майже кожна публічна веб-служба використовує такий проксі.

Мнемоніка: проміжний проксі ховає клієнтів від серверів. Зворотний проксі ховає сервери від клієнтів.

Чому важливо знати, який саме це проксі? Функції, режими відмов та межі безпеки відрізняються. Проміжний проксі турбується про те, з ким спілкуються його користувачі; зворотний проксі турбується про те, хто звертається до його серверів.

Клієнт, який надсилає трафік одночасно крізь обидва типи проксі, проходить шлях: client -> forward_proxy -> internet -> reverse_proxy -> origin.

Невелика компанія експлуатує чат-додаток. Вони хочуть, щоб запити кожного зовнішнього користувача надходили на машину, яка ховає за собою реальні сервери чату. Який тип проксі їм потрібен, і з чим фактично з'єднується зовнішній користувач?

Чому стільки функцій виконується на краю мережі

Крайовий шар виправдовує свою вартість

Зворотний проксі одночасно виконує три завдання. Будь-яке з них окремо виправдовує наявність цього шару; виконання всіх трьох завдань на одній адресі пояснює, чому майже кожна продуктивна веб-архітектура має однакову структуру на фронтенді.

Завдання 1: Приховати початковий сервер. Проксі відповідає на публічному IP. Бекенди розташовані на приватних IP, до яких Інтернет не має доступу. Нападнику, який хоче атакувати початковий сервер, спершу потрібно скомпрометувати проксі.

Завдання 2: Завершення TLS. Проксі зберігає сертифікат для example.com та розшифровує вхідні HTTPS-запити. Бекенди спілкуються з проксі за допомогою звичайного HTTP (або простішого внутрішнього TLS) через довірену мережеву сегмент. Ротація, оновлення сертифікатів та політика шифрування зосереджені в одному місці.

Завдання 3: Розподіл навантаження. Проксі обирає, який бекенд оброблятиме кожен запит. Бекенди за одним проксі утворюють пул; проксі обирає один із них для кожного запиту за допомогою стратегії (round-robin, найменше з'єднань, хеш за заголовком). Додавання потужності означає додавання бекенду до пулу, а не інформування кожного клієнта про нову адресу.

Кожне завдання — це невелика програма. Разом вони пояснюють, чому шар, настільки простий, як «Caddy перед Python-додатком», несе більше проєктного навантаження, ніж сам Python-додаток.

Проксі, що виконує три завдання: приховування походження, завершення TLS, розподіл навантаження

Проєктування для всіх трьох завдань

Ваша команда запускає невеликий API на одному Python-процесі, який слухає порт 8000 на одній віртуальній машині. Трафік зріс настільки, що одна віртуальна машина не встигає, а безпековий аудит виявив, що віртуальна машина має публічний IP та використовує власний TLS-сертифікат.

Ви вирішили розмістити реверсний проксі перед додатком. Намалюйте схему: куди вказує DNS, де зберігається сертифікат, як навантаження потрапляє до бекендів та що змінюється щодо початкової віртуальної машини?

Розгляньте нову архітектуру. Розкрийте всі чотири аспекти: ціль DNS, місце завершення TLS, стратегію розподілу навантаження та те, що початкова віртуальна машина зберігає або втрачає.

Заміна компонента без помітних змін для користувачів

Посередництво забезпечує свободу

Стара комп'ютерно-наукова прислів'я стверджує: будь-яку проблему можна вирішити, додавши шар посередництва (окрім проблеми надмірної кількості шарів посередництва). Зворотний проксі-сервер є одним із найкорисніших механізмів посередництва в розподілених системах.

Що це дає:

- Замінювані бекенди. Перенесення додатка з Python на Go? Міграція з одного дата-центру в інший? Розгортання нової версії без простою? Кожна з цих дій відбувається за стабільною публічною адресою. Для користувачів нічого не змінюється.

- Незалежне масштабування. Шар проксі-сервера масштабується за пропускною здатністю та CPU на рівні TLS. Шар бекенду масштабується за обсягом додаткової роботи. Кожен росте у власному вимірі, оскільки вони працюють на різних машинах.

- Ізоляція збоїв. Погане розгортання на бекенді не вимикає публічну адресу. Проксі-сервер продовжує працювати; ви вносите виправлення або відкатюєте зміни; світ знову з'єднується, коли бекенд відновлюється.

- Поперечні питання в одному місці. Обмеження частоти запитів, гео-блокування, логування запитів, переписування заголовків, кешування, стиснення відповідей: все це реалізується на проксі-сервері. Код бекенду залишається зосередженим на додатку.

Без проксі-сервера кожна з цих проблем має існувати всередині процесу додатка. З проксі-сервером вони існують на одному шарі, за який відповідає одна команда.

Ціна: ще один шар для обслуговування. Досвідчені команди приймають цю ціну, оскільки сам шар проксі-сервера працює без стану та масштабується горизонтально; заміна одного проксі-сервера двома не потребує координації.

Blue/Green розгортання через проксі

Ваша команда запускає версію 1 API на трьох бекенд-VM (синій пул) за зворотним проксі. Ви хочете розгорнути версію 2 з можливістю відкату назад менш ніж за тридцять секунд, якщо щось піде не так.

Ви запускаєте три нові бекенд-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: Вибір бекенду. Проксі звертається до свого пулу upstream-серверів для api.example.com і обирає один бекенд (наприклад, 10.0.0.21:8000) за допомогою своєї стратегії балансування навантаження.

Крок 5: Upstream-запит. Проксі відкриває (або повторно використовує) звичайне HTTP-з'єднання з 10.0.0.21:8000 та пересилає запит. Проксі може змінювати заголовки під час передачі: додавати X-Forwarded-For: <client-ip>, коректно встановлювати Host:, видаляти hop-by-hop заголовки, такі як Connection.

Крок 6: Обробка бекендом. Бекенд-додаток читає запит, виконує запити до бази даних та формує JSON-відповідь.

Крок 7: Upstream-відповідь. Бекенд надсилає відповідь назад до проксі як звичайний HTTP.

Крок 8: Відповідь на рівні краю мережі. Проксі може змінити або стиснути відповідь, шифрує її назад через TLS-сесію та надсилає її в браузер.

Крок 9: Життєвий цикл з'єднання. TLS-сесія зазвичай залишається відкритою для наступного запиту (HTTP/2 мультиплексує багато запитів на одному з'єднанні). З'єднання між проксі та бекендом часто пулюється для повторного використання.

Кожний публічний веб-сервіс дотримується певної варіації цієї схеми. Знання кроків дозволяє робити висновки про те, де накопичується затримка, де має знаходитися логування та де може приховуватися збій.

Життєвий цикл запиту: браузер, DNS, проксі, TLS, upstream, бекенд, відповідь

Куди зник час?

Користувник скаржиться, що API працює повільно. Ви вимірюєте та виявляєте, що запит займає 850 мс від початку до кінця. Журнали сервера на бекенді показують, що застосування обробило запит за 40 мс. Журнали проксі показують, що проксі витратив 50 мс на свою частину роботи (рукопожаття TLS + маршрутизація + запис відповіді).

Куди ж ділися інші 760 мс? Назвіть принаймні дві кандидатури, які перебувають поза часом обробки проксі та бекенду, та поясніть, як кожна з них проявиться в вимірюваннях.

Проєктуйте мінімальний край для нового сервісу

Синтез

Ви навчилися розрізняти прямий та зворотний проксі, зрозуміли три завдання, які зворотний проксі виконує одночасно, чому приховування початкового сервера (origin) приносить вигоду щоразу, коли потрібно щось змінити, та як запит проходить крок за кроком через крайову точку.

Тепер застосуйте це.

Невелика команда планує запустити новий сервіс під назвою notes.example.com. Користувачі зможуть читати та писати особисті нотатки. На момент запуску команда запустить два бекендні віртуальні машини та очікує масштабування до десяти протягом наступного року. Вони хочуть HTTPS для користувачів, поступове впровадження нових версій та відсутність публічного доступу до IP-адрес бекендів.

Проєктуйте архітектуру краю для notes.example.com. Розгляньте: куди вказує DNS, де зберігається TLS-сертифікат, як запити доходять до бекенду, що змінюється, коли вони масштабуються з двох до десяти бекендів, та одну поперечну проблему (обмеження швидкості, логірування, переписування заголовків тощо), яку ви б додали на рівні краю, а не всередині застосунку.

Куди веде цей курс далі

Куди веде цей курс далі

У цьому уроці було визначено структуру крайнього шару. Ще чотири уроки в цьому курсі будуються на її основі:

- Безстанове горизонтальне масштабування: чому проксі-шар (та бекенди за ним) легко масштабується, та математика для визначення кількості реплік під час пікових навантажень.

- Розділення вхідного та вихідного трафіку: чому один проксі-вузол, який обробляє як вхідний, так і вихідний трафік, зрештою дає збій несподіваними способами, та як розділити ці шари.

- Режими збою та масштаб впливу: як одна зміна конфігурації може призвести до каскадного виходу з ладу, та як формулювати безвинні дії, що запобігають повторенню інцидентів.

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

Кожен урок є самодостатнім. Разом вони дають вам робочу ментальну модель веб-масштабного флоту.

Супутній урок: geometry_of_proxies_and_origins переосмислює все з цього уроку як орієнтований граф та досліджує, що теорія графів говорить про шлях запиту.

Молодець. Далі.