Представьте двух покупателей одного и того же сервиса записи на услуги. Один сидит в офисе в Нью-Йорке и открывает сайт с гигабитного оптоволокна. Другой стоит на парковке в Сан-Диего и оформляет запись с телефона через мобильную сеть, где сигнал то есть, то нет. Для отчёта по трафику это «два американских пользователя». Для сервера это два разных пути, две разные цепочки пересылок и два разных ощущения от одной кнопки «Записаться».

Поэтому вопрос «какой VPS взять для США» почти всегда оказывается неполным. Правильнее спрашивать иначе: какие именно действия совершают клиенты, откуда они приходят и из чего складывается время до результата. Расстояние на карте входит в ответ, но только одной частью. Остальное прячется в DNS, установке соединения, шифровании, работе приложения, базе данных и сторонних сервисах, к которым ваш код обращается за кулисами.

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

Сначала разложим аудиторию, а не усредним её

Возьмём условный сервис онлайн-записи для сети студий. Допустим, у него 10 000 сеансов в сутки, и по аналитике они распределены так (числа выдуманы для примера):

Условное распределение сеансов по регионам
РегионСеансов в суткиДоля
Северо-восток (Нью-Йорк, Бостон, Филадельфия)4 20042%
Калифорния2 30023%
Средний Запад (Чикаго и окрестности)1 30013%
Техас1 20012%
Юго-восток1 00010%

Что из такой таблицы следует? Во-первых, аудитория не делится пополам между побережьями. Почти половина клиентов живёт на северо-востоке, и это уже довод в пользу точки размещения ближе к восточной части страны. Во-вторых, четверть клиентов находится на другом краю континента, и их опыт нельзя игнорировать только потому, что их меньше. В-третьих, эти доли относятся к сеансам, а не к деньгам. Если калифорнийцы покупают дорогие абонементы, а северо-восток в основном листает расписание, вес регионов для бизнеса окажется другим. Сначала решите, что считаете важным: число визитов, число оплат или выручку.

Вторая ось, о которой часто забывают, это тип подключения. Домашний провайдер, корпоративная сеть и мобильный оператор по-разному доходят до одного и того же сервера. Поэтому «Нью-Йорк» в тестах лучше разбить хотя бы на две сети: проводной доступ и мобильный. Если у вас нет возможности проверять мобильные сети, честно зафиксируйте это ограничение в своих выводах: отсутствие замера ничем не лучше плохого замера.

Третья ось: что вообще делает пользователь. Просмотр главной страницы, поиск свободного окна, вход в личный кабинет и оплата нагружают разные части системы. Страница, которая целиком состоит из статических файлов, чувствительна в основном к сети. Поиск свободных слотов обращается к базе. Оплата ходит во внешний платёжный сервис. Один и тот же сервер покажет для этих сценариев разные картины, так что измерять нужно не «сайт», а пользовательские действия.

Путь одного запроса: где именно уходит время

Когда браузер открывает страницу по HTTPS, он не просто «отправляет запрос». Сначала нужно узнать IP-адрес по имени, затем установить TCP-соединение, затем согласовать шифрование, и только потом запрос уходит на сервер. Сервер что-то считает, обращается к базе и начинает отвечать. Каждая из этих фаз зависит от разных обстоятельств, и именно поэтому одна общая цифра «страница грузится 500 мс» почти ничего не объясняет.

Инструмент, который позволяет разложить запрос на фазы без специальных программ, это curl. У него есть переменные для вывода времени после завершения операции. По руководству curl, time_namelookup, time_connect и time_appconnect отсчитывают время от начала операции до завершения разрешения имени, TCP-соединения и TLS-рукопожатия соответственно. Поле time_starttransfer включает подготовку и обработку запроса сервером до получения первого байта, а time_total это полная длительность. Принципиально важно, что эти значения накопительные: каждое отсчитывается от старта, поэтому их нельзя просто сложить как независимые этапы.

Команда может выглядеть так:

curl -o /dev/null -s -w 'dns=%{time_namelookup} tcp=%{time_connect} tls=%{time_appconnect} first_byte=%{time_starttransfer} total=%{time_total}\n' https://example.com/

Адрес замените на свой. Ответ тела уходит в никуда, а на экране остаётся строка из пяти накопленных значений. Теперь посмотрим, как её читать.

Числовой пример: две сети, одна страница

Допустим, мы запустили команду на двух машинах: одна стоит в проводной сети на северо-востоке США, другая подключена через мобильного оператора в Калифорнии. Значения условные, в секундах, и сервер в обоих случаях один.

Накопленные значения curl (условный пример)
ПолеСеверо-восток, проводная сетьКалифорния, мобильная сеть
time_namelookup0,0300,020
time_connect0,0550,090
time_appconnect0,1100,200
time_starttransfer0,3900,470
time_total0,4300,520

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

  • DNS. Первое значение уже и есть длительность разрешения имени: 30 мс и 20 мс.
  • TCP-соединение. 55 − 30 = 25 мс на северо-востоке и 90 − 20 = 70 мс в Калифорнии.
  • TLS-рукопожатие. 110 − 55 = 55 мс и 200 − 90 = 110 мс.
  • Ожидание первого байта. 390 − 110 = 280 мс и 470 − 200 = 270 мс. В эту фазу входят передача запроса, работа сервера и начало обратного пути ответа.
  • Получение остального ответа. 430 − 390 = 40 мс и 520 − 470 = 50 мс.

Проверка арифметики: 30 + 25 + 55 + 280 + 40 = 430, а 20 + 70 + 110 + 270 + 50 = 520. Суммы сходятся с time_total, а вот если бы мы сложили сами накопленные поля (30 + 55 + 110 + 390 + 430), получилась бы бессмыслица в 1 015 мс.

Теперь о выводах. Фазы, которые зависят от дороги, сильно различаются: до готовности защищённого канала северо-востоку нужно 110 мс, а Калифорнии 200 мс. Разница в 90 мс целиком сетевая, так как сервер к рукопожатию не привязан. Зато ожидание ответа почти одинаково, 280 и 270 мс. Это сигнал, что бо́льшая часть времени уходит не на дорогу, а на работу приложения. Если перенести сервер на побережье и сократить сетевые фазы вдвое, страница станет быстрее лишь на часть общего времени, а основная доля в виде почти трёх десятых секунды останется на месте.

Заметим и подвох: ожидание первого байта само по себе включает пересылку запроса и возврат первого пакета, то есть тоже содержит сетевую составляющую. Чтобы вычесть чистую работу сервера, измерьте тот же URL с самой машины, где стоит приложение (например, через локальный адрес с нужным заголовком Host). Если локально первый байт приходит через 240 мс, то остаток от 280 мс на северо-востоке и от 270 мс в Калифорнии это сеть. Если же локальный результат уже 270 мс, приложению нужна оптимизация, а не новое расположение.

Как не обмануть себя повторами

Один запуск curl это один случайный пример. DNS может отдать ответ из кеша резолвера, и тогда первое поле почти обнулится. Соединение может установиться неудачно, и в выводе появится выброс. Поэтому делайте серию запусков в разное время суток, смотрите на медиану и на хвост (например, на худшие из двадцати запусков), а не на лучший результат. Для пользователя важнее не среднее, а то, как часто ему попадается медленный ответ.

Сеть отдельно, приложение отдельно

Чтобы не гадать, где проблема, разделяйте два вида измерений. Первый показывает, как до сервера добираются пакеты из нужных сетей. Второй показывает, сколько приложение думает над запросом. Смешивать их опасно: медленный backend легко принять за «далёкий дата-центр» и потратить деньги на переезд, который ничего не изменит.

Для первого вида измерений подходит платформа RIPE Atlas. Среди пользовательских измерений там доступны Ping, Traceroute, DNS, TLS и NTP, а HTTP-измерения ограничены и разрешаются индивидуально. Пробники можно выбирать по стране, ASN, префиксу и идентификатору, то есть можно взять зонды именно в США и даже в нужных операторах. Нужно помнить два условия: указанный пробник может оказаться занятым или недоступным, а сами измерения расходуют кредиты и подчиняются квотам. Поэтому заранее закладывайте запас в выборке и не строите вывод на одном зонде.

Что это даёт на практике? Ping и Traceroute покажут, как растёт задержка и где путь делает неожиданный крюк, а TLS-измерение даст сопоставимую картину со второй фазой curl. Если же вам нужен полноценный HTTP-замер страницы с вашим приложением, ограничение платформы подсказывает другой путь: запустить curl на нескольких собственных или арендованных машинах в нужных регионах и собрать цифры самим.

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

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.

АРЕНДОВАТЬ СЕРВЕР

Что стоит за приложением: база и внешние сервисы

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

Покажем это арифметикой на условном примере. Предположим, что страница поиска делает 12 последовательных запросов к базе, а между приложением и базой задержка в одну сторону и обратно составляет 70 мс. Тогда на одни только переезды уйдёт 12 × 70 = 840 мс, причём независимо от того, сколько времени сама база тратит на обработку. Если же и приложение, и база находятся на одном VPS, этот слагаемый практически исчезает. Отсюда простое правило: сначала держите приложение и базу рядом, а уже потом думайте о том, как приблизить всё это к пользователю.

Второй источник скрытой задержки это внешние API: платёжные системы, карты, почтовые рассылки, проверка адресов. Для них полезно измерить время отклика прямо с вашего VPS: запустите curl с сервера в сторону нужного API и посмотрите на те же фазы. Смотреть надо не только среднее значение, но и частоту ошибок и таймаутов. Не стоит заранее считать стороннюю службу одинаково доступной из любой страны и любой сети: проверка с реального сервера и есть единственный надёжный ответ. Ограничение по IP-адресам или регионам у партнёра тоже обнаруживается только практикой.

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

Что можно раздать из кеша, а что нет

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

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

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

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

Сколько стоит архитектура, и когда она окупается

Теперь соберём варианты в одну картину, возвращаясь к условной аудитории из таблицы выше. Допустим, интересуют три схемы.

  1. Один VPS в США. Простое решение: одно приложение, одна база, один адрес. Все пользователи получают одинаковый сервер, и разница между ними определяется только дорогой. Минимум забот с согласованностью данных.
  2. Один VPS плюс кеширование статики. Динамика по-прежнему идёт в одно место, а тяжёлые файлы раздаются ближе. Хороший шаг, когда замеры показывают, что основной вес страницы это скачивание ресурсов.
  3. Несколько серверов в разных регионах. Теоретически снижает дорогу для далёких клиентов, но немедленно создаёт вопросы: где хранится база, как синхронизируются записи, что происходит при конфликтах, как переключать трафик. Это уже не покупка ещё одного сервера, а проектирование распределённой системы.

Что говорит арифметика нашего примера? Северо-восток даёт 42% сеансов, а с Центром и Югом, которые тоже ближе к восточной половине страны, получится уже заметно больше половины аудитории. Для такой структуры одна площадка рядом с востоком подходит как основная. Калифорнийцы при этом получают сетевые фазы заметно длиннее. Но если, как в нашей таблице curl, у них на ожидание ответа уходит 270 мс, а на сетевые фазы дополнительные 90 мс, то выгода от второй площадки составит часть этих 90 мс, а цена в виде репликации базы и усложнённой эксплуатации будет постоянной.

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

Теперь о ресурсах VPS. В публичном предложении MAATRIX среди локаций указаны UK, US, RU и FR, а у VPS заявлены NVMe, AMD EPYC и root-доступ. Для пилота хватит и небольшого плана: например, Ba с 1 vCPU, 2 ГБ RAM и 40 ГБ NVMe, либо Uab с 2 vCPU и 4 ГБ, если нужно проверить приложение с базой на одной машине. Эти ресурсы служат отправной точкой для теста, а не обещанием ёмкости: сколько одновременных клиентов выдержит приложение, покажет нагрузка, а не строка каталога. Конкретные подробности наличия и образов проверяются в форме заказа. Город и сеть конкретного размещения тоже уточняйте там же и затем подтверждайте измерением: трассировка и curl с нужных сетей расскажут больше любых описаний.

Практически важно и то, что оплата картой РФ или через СБП и автоматическое создание VPS в течение пары минут после оплаты делают пробу недорогой по времени. Можно арендовать площадку в США, провести серию замеров, сравнить с альтернативой в другой локации и принять решение по цифрам. Есть и смежные сценарии: например, сервис, где клиентами служат телефоны в пути, как в материале про Dawarich на своём сервере, с самого начала плохо описывается одним «пользователем на карте», и там тоже полезно мерить реальные сети, а не точку на схеме.

Пороги: когда измерение превращается в решение

Набор чисел сам по себе ничего не решает. Нужно заранее договориться, что считать приемлемым. Для нагрузочных проверок удобен подход, при котором условие прохождения записывается в сам тест. В Grafana k6 такие условия называются thresholds: они задают требования к метрикам, например к задержке или частоте ошибок, а если условие не выполнено, тест завершается неуспешно. Это удобно тем, что решение «годится или нет» перестаёт зависеть от настроения того, кто смотрит на график.

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

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

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

Порядок пилота

Соберём всё в последовательность, которую можно пройти за несколько дней.

  1. Выберите два-три главных региона по вашей аналитике и определите, какая сеть в каждом из них типична для клиентов.
  2. Опишите два-три ключевых пользовательских действия: открыть каталог, найти слот, оформить запись.
  3. Арендуйте VPS в нужной локации и разверните на нём приложение вместе с базой, чтобы не добавлять лишнюю дорогу внутри системы.
  4. Запустите curl с разбивкой по фазам из нужных регионов, сделайте серию замеров в разное время суток и разложите накопленные значения на длительности этапов.
  5. Повторите запросы локально на сервере и вычтите их из ожидания первого байта, чтобы отделить дорогу от работы приложения.
  6. Проверьте отклик внешних API с самого VPS и отметьте таймауты.
  7. Задайте пороги по хвосту времени и доле ошибок для каждого ключевого действия и прогоните нагрузочный тест.
  8. Только после этого сравнивайте варианты размещения и решайте, нужен ли второй регион.

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

Проверка, которая стоит последней

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

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