RE:NODE

Эксплуатация12 мин чтения

Staging и production на одном аккаунте хостинга

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

Обновлено

0 прочтений

Запустите второй, поменьше сервер с теми же версиями программ, свежей копией настоящих данных с обезличенными персональными частями и собственными учётными данными, которые ни к чему настоящему не подключаются. Деплойте сначала туда, каждый раз, и никогда не правьте его руками, чтобы тест прошёл. Это и есть staging-окружение, а в панели оно стоит один дополнительный небольшой тариф - на момент написания от $4 в месяц на линейках приложений, - что меньше, чем один неудачный вечер на боевом сервере.

Проверять обновление на боевом сервере нормально ровно до того вечера, когда это перестаёт быть нормальным. Ценность staging не в том, что он находит баги, - по большей части не найдёт. Ценность в том, что это единственное место, где обновление может упасть без чужих глаз, и в том, что он заставляет записать, из чего на самом деле состоит «деплой».

Для чего нужен staging-сервер и для чего не нужен#

Определите задачу точно, потому что расплывчатый staging-сервер - это тот, которым вы перестанете пользоваться через месяц.

Это репетиция деплоя, а не репетиция кода. Код был проверен на вашем ноутбуке. Не проверялась именно эта последовательность: эта версия рантайма, эти файлы конфигурации, эта миграция, на данных, устроенных как настоящие, на машине с таким объёмом памяти. Ломается именно эта последовательность, и её как раз не воспроизвести на ноутбуке.

Сюда первыми приходят обновления версий. Новая версия игры, новая Java, новый плагин, новая мажорная версия базы данных. Всё, где сбой выглядит как «мир открывается и незаметно изменён», должно оказаться на копии до того, как дотронется до оригинала.

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

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

Копируйте это в точности#

Смысл staging в тождественности, поэтому список того, что копировать, короток и неумолим:

  • Каждый номер версии. Версия игры или рантайма и точная сборка. «Paper 1.21.1» - это не версия, а paper-1.21.1-132 - версия. Для приложения это значит ту же минорную версию Node или Python и установку из lock-файла, а не из диапазона в package.json. Разница между npm ci и npm install - это именно разница между staging-сервером, отражающим production, и тем, что отражает момент времени; длинная версия - в статье npm ci или npm install.
  • Каждый мод, плагин или зависимость в той же версии и в том же порядке загрузки.
  • Файлы конфигурации, за вычетом всего, что содержит учётные данные. Те же настройки tick, то же расстояние прорисовки, то же число рабочих процессов, те же флаги памяти там, где они совместимы с меньшим тарифом.
  • Свежая копия мира или базы данных, чтобы тест шёл на данных реальной формы: база с 900 таблицами плагинов, база с 40 000 блоков, игрок с инвентарём, полным граничных случаев. Синтетические данные ничего интересного не проверяют.
  • Команда запуска и её аргументы, то есть в панели - поля вкладки Startup, и именно там на самом деле живёт половина всех загадок «на staging работает».

Быстрее всего получить достоверную копию через backup. Сделайте его на production, скачайте, загрузите на staging и распакуйте на месте. У этого есть приятный побочный эффект: ваш путь восстановления регулярно проверяется; почему это важнее, чем сам факт наличия backup, объясняет статья проверка восстановления до того, как оно понадобится.

Различайте это намеренно#

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

ЧтоProductionStaging
База данныхСвой экземпляр и пользовательОтдельный экземпляр, отдельный пароль
ПочтаНастоящий SMTPЯщик, принимающий всё, или ничего
ПлатежиБоевые ключиТолько тестовые или sandbox-ключи
Бот Discord или TelegramНастоящий токен, настоящий guildВторой бот, закрытый тестовый guild
WebhooksНастоящие каналыМёртвый канал, который вы не читаете
Доменapp.example.comstaging.example.com, noindex
BackupПолное расписаниеНеобязательно. Он одноразовый по замыслу
ДоступНаименьшие привилегииВсе, кому нужно тестировать

Два из этих пунктов заслуживают большего, чем строка таблицы.

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

Персональные данные. Копия данных production - это копия данных ваших пользователей, лежащая на сервере со свободнее устроенным доступом. Вычищайте её в рамках импорта, а не потом:

sql
UPDATE users SET  email = 'user' || id || '@example.invalid',  phone = NULL,  password_hash = '$2y$12$notarealhashnotarealhashnotarealhash1234567890ab';DELETE FROM sessions;DELETE FROM api_tokens;UPDATE payment_methods SET last4 = '0000', token = NULL;

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

Размер второго сервера#

Смысл в том, чтобы он был меньше, - поэтому staging и доступен по цене, - но три вида «меньше» обесценивают тест, и полезно знать какие.

Безопасно уменьшать: диск, пока помещается копия данных; число выделенных портов; слоты backup; и CPU, из-за чего всё будет медленнее, но поведение не изменится.

Небезопасно уменьшать: память, когда проверяется то, что связано с памятью. Сборка модов, которой нужно 6 ГБ, не запустится на 2 ГБ, и «упало на staging» тогда ничего вам не говорит. Число рабочих процессов, если его уменьшить, скроет все ошибки конкурентности. А любой жёсткий лимит, к которому вы приближаетесь на production, - размер пула соединений, потолок кучи - должен быть тем же числом, иначе тест измеряет другую систему. Обычно об это спотыкаются в теме пулы соединений и лимиты.

Разумный вариант по умолчанию для приложения - тот же тариф на ступень ниже: тот же рантайм, вдвое меньше памяти и те же переменные окружения, кроме тех, что обязаны отличаться. Для игрового сервера сохраните память и урежьте диск, потому что тест обычно про память. Линейки приложений, веб-хостинга и баз данных RE:NODE получают одну и ту же панель независимо от тарифа - консоль, файловый менеджер, SFTP, слоты backup, расписания, subusers, - так что небольшой staging-тариф - это не урезанная панель, а лишь урезанное оборудование.

деплой при pushпроверкапродвинуть ту же сборкуперед каждым релизомGit-репозиторийветка mainСервер stagingнебольшой тарифВаш чек-листзапуск, smoke-тестСервер productionнастоящийBackupдо деплоя
Одно изменение, два сервера, по порядку

Как не дать двум серверам разойтись#

Дрейф - это способ, которым убивают staging-окружения. Он всякий раз происходит одинаково: что-то ломается на production в 23:00, кто-то исправляет это прямой правкой файла, и никто не делает ту же правку на staging. Через три недели staging говорит, что релиз в порядке, а production не согласен, все решают, что staging бесполезен, и его отменяют.

Честным его держат три привычки.

Изменения текут в одну сторону. Всё, что меняет production, должно сначала применяться к staging тем же механизмом. На линейках приложений этот механизм - Git: деплой RE:NODE идёт через GitHub с помощью GitHub App с короткоживущими токенами, чтобы работали приватные репозитории, и с двумя переключателями - pull при каждом запуске и деплой при push. Деплой при push перезапускает только уже работавший сервер, а это полезное свойство для staging: оставьте его остановленным между тестами, и он подхватит всё при следующем запуске. Настройка разобрана в статье деплой приложения Node из GitHub.

Аварийные исправления воспроизводятся в течение суток. Не «когда дойдут руки». Запишите это в заметке об инциденте: исправление не закончено, пока его нет в репозитории и на staging.

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

bash
$ ls -1 plugins/*.jar | xargs -n1 basename | sort > prod-plugins.txt$ ls -1 plugins/*.jar | xargs -n1 basename | sort > staging-plugins.txt$ diff prod-plugins.txt staging-plugins.txt$ diff <(sort prod-server.properties) <(sort staging-server.properties)

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

bash
$ node --version && cat package-lock.json | head -5$ printenv | cut -d= -f1 | sort > env-names.txt

Различие в наборе имён переменных - лучшее из существующих раннее предупреждений. Переменная, которая есть на production и отсутствует на staging, означает, что следующий деплой запустит процесс, читающий undefined и ведущий себя так, как никто ещё не видел.

Чего staging не поймает#

Скажем это прямо, чтобы никто не строил на этом ложную уверенность.

Нагрузку. Три человека, щёлкающие по сайту, - это не сорок игроков, заходящих в 19:00. Ошибки конкурентности, конкуренция за блокировки, исчерпание пула соединений и рост памяти при устойчивом трафике невидимы на простаивающем staging-сервере.

Объём данных. Запрос, мгновенный на 400 МБ, может оказаться полным сканированием таблицы на 40 ГБ. Если копия на staging - урезанное подмножество, любой вывод о производительности из неё неверен. Копируйте всё целиком или признайте, что производительность вы не проверяете.

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

Поведение сторонних сервисов. Sandbox-API - это не настоящий API. Лимиты запросов, частичные сбои и данные с полями, которых нет в документации, случаются только в production.

Разовые случаи. Плагин, читающий файл, существующий только на production, DNS-запись, которая отличается, правило firewall, добавленное кем-то вручную. Это ровно проблема дрейфа, описанная выше, поэтому процедура сравнения важнее, чем само тестирование.

С учётом этого списка честная формулировка такова: staging ловит падение деплоя, падение миграции, неверную конфигурацию и несовместимость версий. Это четыре из пяти вещей, которые идут не так в вечер релиза. Пятая - нагрузка, а с нагрузкой имеют дело backup и план отката.

Как на самом деле выглядит релиз#

Ниже приведённая процедура - и есть результат. Свою стоит записать в репозитории, даже если она короче этой.

  1. Слейте изменение. Staging деплоится из репозитория автоматически или при вашем следующем запуске.
  2. Запустите staging и прочитайте лог с самого начала. Баннер запуска показывает версии, которые действительно загрузились. Сравните их с production.
  3. Сначала выполните миграцию на staging и засеките время. Миграция, занимающая 40 секунд на staging при десятой части данных, - это четыре минуты простоя на production, если вы не напишете её так, чтобы избежать блокировок; паттерны описаны в статье миграции без простоя.
  4. Smoke-тест. Шесть пунктов, каждый раз одни и те же: войти, выполнить основное действие, проверить то, чего коснулось изменение, проверить одну вещь, которой оно точно не должно было касаться, проверить путь администратора, проверить лог на новые предупреждения.
  5. Сделайте backup production. Перед чем угодно, каждый раз. Это и есть откат.
  6. Задеплойте ту же сборку на production. Не пересборку и не «тот же коммит, собранный ещё раз» - тот же артефакт, если возможно, и как минимум тот же хеш коммита.
  7. Наблюдайте первые пять минут. Новые предупреждения в логе, память и график. Если плохо, откатывайтесь сразу, а не разбирайтесь на живом сервере.
  8. Запишите всё, что вы сделали руками, и в тот же день воспроизведите это на staging.

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

Одно замечание о доступе: людям, которые тестируют, не нужны права на оплату и возможность удалить сервер. В RE:NODE есть subusers, роли и команды с детальными правами - только консоль, только файлы, без оплаты - с ограниченным по времени доступом и журналом действий по каждому серверу, и это правильная форма для staging-окружения, в котором копаются несколько человек. Разделение описано в статье subusers и наименьшие привилегии.

FAQ#

Нужен ли мне staging-сервер для небольшого сервера сообщества?

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

Можно ли staging и production использовать одну базу данных, если быть осторожным?

Нет. Это единственное правило в статье без исключений. Общие базы означают, что миграция на staging может уничтожить данные production, а ошибка на staging может записать бессмыслицу, которую потом отдаст production. Отдельные экземпляры, отдельные учётные данные, а staging вообще не должен иметь возможности достучаться до production.

Как не допустить, чтобы staging отставал на месяцы?

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

Должен ли staging быть того же размера, что и production?

Сохраните память и любые жёсткие лимиты, против которых тестируете, остальное уменьшите. Половина CPU делает staging медленнее, что безвредно. Половина памяти меняет поведение, что небезвредно, особенно для игрового сервера с модами или JVM, где проверяется как раз размер кучи.

Стоит ли платить за второй сервер только ради тестов?

Один раз сравните это со стоимостью альтернативы. Небольшой тариф приложения или игры - несколько долларов в месяц, а более долгие сроки дешевле в пересчёте на месяц. Один потерянный вечер, один испорченный мир или одна миграция, выполненная на боевых данных, стоят больше, чем год работы второго сервера. Бесплатного тарифа здесь нет, так что это реальные расходы, просто небольшие.

Можно ли использовать один staging-сервер для нескольких проектов?

Можно, если они не работают одновременно и вы дисциплинированно чистите сервер между ними. Это хуже, чем по одному на проект, потому что остатки от прошлого проекта - именно тот вид различий, из-за которого тест лжёт, но это намного лучше, чем отсутствие staging вообще.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000