Вибір хостинг-провайдера - це не просто питання ціни за гігабайт пам'яті. Для складних CRM-систем, ERP-рішень та високонавантажених веб-проектів, які розробляє Skylex, інфраструктура є фундаментом безпеки та швидкості. Помилка у виборі дата-центру може коштувати бізнесу годин простою та втрати лояльності клієнтів.
Як ми перенесли продакшн-інфраструктуру на нові сервери та прискорили проєкт у 5 разів
Що відбувається після того, як сервери піднялися
Перенесення великого проєкту на нову інфраструктуру рідко закінчується на етапі, коли сервери просто запустилися. Багато хто думає, що якщо сайт відкрився, то роботу виконано. На практиці все інакше.
Справжній продакшн вимагає ретельної перевірки після міграції. Треба переналаштувати внутрішні підключення, переписати конфіги, закрити доступи до сервісів. І головне - знайти причини, чому нове середовище спочатку може працювати навіть повільніше за старе.
Ми перенесли великий e-commerce проєкт на сервери Hetzner через snapshots. Налаштували безпечну приватну мережу між машинами, прибрали пастки зі старими конфігами та впровадили рішення, яке дало п'ятикратне прискорення сайту. Це локальний Redis прямо на веб-сервері.
Стартова архітектура: Як були розподілені ресурси
На самому початку інфраструктура проєкту жила на трьох окремих машинах. Перша - Web server, де крутився безпосередньо код застосунку. Друга - Database server під керуванням MySQL/MariaDB. Третя - окремий сервер під інфраструктурні сервіси, куди винесли RabbitMQ, Redis та ElasticSearch.
Для переїзду ми вирішили використовувати snapshots існуючих машин. Метод зручний. Він дозволяє швидко отримати точну копію знайомого середовища та розгорнути його на новому залізі Hetzner, не збираючи все з нуля.
Але тут є підвох. Разом із системою та файлами ми копіюємо старі конфіги. А це означає, що всі приховані залежності, змінні середовища та жорсткі прив'язки до localhost теж переїжджають. Після того, як сервери отримали нові IP у Private Network, ці старі зв'язки просто перестають працювати.
Що ми перевіряли в першу чергу
Коли нові машини завелися, ми не стали одразу пускати туди живий трафік. Потрібно було переконатися, що продове середовище дійсно готове.
Ми склали чек-лист для швидкої перевірки. Пройшлися по налаштуваннях мережі між серверами, перевірили доступність бази, черг та кешу. Подивилися на внутрішні DSN-рядки.
Окремо оцінили, як поводиться застосунок під технічним навантаженням та яка швидкість відповіді сторінок. Тільки такий підхід дозволяє виловити приховані проблеми до того, як їх помітять реальні покупці.
План переключення: 40 хвилин жорсткої «червоної зони»
Сам процес міграції та підготовки тривав кілька годин. Проте найвідповідальнішу, критичну фазу переключення ми стиснули в чітке 40-хвилинне вікно. Працювали за суворим планом, щоб мінімізувати простій магазину.
Спочатку ми перенесли домен зі старої айпі-адреси на новий IP в Hetzner. Далі повністю зупинили веб-частину на старому сервері - вирубили fpm, nginx та крони. Слідом зупинили редіс.
Після цього настав етап роботи з базою. Ми зробили фінальний бекап MySQL на старій машині і повністю заглушили її там. Наступний крок - перенесли цей свіжий зліпок даних на новий сервер і запустили базу вже на новому обладнанні. Тільки після цього ми дали команду на старт веб-сервера.
Коли код та база ожили, ми запустили процес копіювання файлів картинок зі старого сервера на новий, щоб клієнти не втратили контент.
Налаштування деплою: Як ми оновили цикл релізів під нове залізо
Коли базові сервіси запустилися, виникло питання з подальшою розробкою. Старий деплой-скрипт був зав'язаний на колишню архітектуру. Нам довелося оперативно переналаштувати deployment-цикл на нові машини Hetzner.
Ми переписали конфіги автоматизації, оновили SSH-ключі доступу та перевірили, як код розлітається по нових серверах. Це було важливо зробити одразу. Команда розробки не повинна чекати, їм потрібен стабільний та зрозумілий інструмент для викатки фіксів у нове середовище без ручних правок через консоль.
Пост-міграційні пастки та їх вирішення
Перша серйозна проблема вилізла з боку RabbitMQ. Одна з CLI-команд у застосунку почала наглухо падати. В логах ми побачили помилку автентифікації AMQP з текстом ACCESS_REFUSED.
Здавалося б, злетіли логін чи пароль. Але коли залізли в конфіги, виявилося, що в DSN-рядку для Messenger банально залишився localhost. Веб-сервер намагався знайти чергу повідомлень у себе під боком, хоча RabbitMQ вже жив на іншій машині. Ми швидко змінили це значення на правильний внутрішній IP всередині Private Network, і команда запрацювала.
Базове закриття HTTP-доступу та безпека бази
Питання безпеки ми вирішували в кілька шарів. Для технічних URL та службових панелей ми швиденько підняли просту захисну стіну - закрили їх через Basic Auth на Nginx. Це відмінне тимчасове рішення для службових інтерфейсів та стейджингу, яке не потребує переписування коду самого сайту.
З базою даних вчинили суворіше. У нас була чітка схема: сервер бази отримав внутрішній IP 10.0.0.2, а веб-сервер - 10.0.0.3.
Ми повністю заборонили MySQL приймати зовнішні підключення. Прописали firewall-правила в Hetzner тільки для IP веб-сервера. На додачу обмежили самого користувача DB user в налаштуваннях бази, щоб він міг підключатися виключно з хоста 10.0.0.3. Якщо один рівень захисту десь дасть збій, інші шари все одно втримають систему від злому.
Міграція ElasticSearch: Переіндексація каталогу без втрати швидкості
Окремим квестом став запуск ElasticSearch на новому інфраструктурному сервері. Оскільки ми гасили стару машину повністю, колишні індекси пошуку стали неактуальними. Після старту на новому залізі застосунок не зміг би нормально шукати товари.
Ми запустили повну переіндексацію каталогу. Для 160,000 товарів це важкий процес, який навантажує систему. Ми оптимізували виділення оперативної пам'яті (Java heap size) під нові параметри сервера Hetzner, щоб індексація пройшла швидко і не забила дискову підсистему. Тепер пошук на сайті знову став миттєвим.
Чому після перенесення просіла продуктивність
Коли сайт увімкнули, ми почали заміряти швидкість. Результати нас не порадували. На старому тестовому сервері база віддавала відповідь в районі 800 мс, а тут ми отримали аж 1500 мс.
Це класичний приклад того, що запуск серверів - це ще не перемога. Ми почали шукати причину. Виявилося, що між веб-сервером і сервером інфраструктури, де спочатку лежав Redis, виникає мережева затримка. Для каталогу на 160 тисяч позицій це «мережеве плече» стало критичним, оскільки застосунок робив занадто багато дрібних запитів до кешу під час генерації сторінки.
Чому ми перенесли Redis на той самий сервер, де працює код
Redis як локальний cache instance прямо на веб-сервері (web server), де крутиться сам код проєкту.
Рішення виявилося найвлучнішим. Швидкість відповіді сайту зросла у 5 разів порівняно зі старою конфігурацією. Застосунок почав смикати гарячі дані миттєво, без прогулянок по локальній мережі. Важкі запити просто перестали доходити до MySQL.
При цьому ми чітко налаштували конфігурацію Redis. Він слухає виключно localhost, захищений паролем у protected-mode, а persistence (запис на диск) ми повністю вирубили для максимального прискорення. Також ми жорстко обмежили ліміт пам'яті та увімкнену політику витіснення ключів LFU.
Бот або система не намагаються запхати туди всі 160,000 товарів. У пам'яті лежать тільки «гарячі» дані - популярні позиції та важкі результати запитів, а все непопулярне Redis вичищає сам.
Моніторинг інцидентів: Як ми підключили BetterStack через Slack
Щоб контролювати нову інфраструктуру у живому режимі, ми розгорнули систему моніторингу і зв'язали її з робочим простором. Ми налаштували BetterStack, який цілодобово перевіряє доступність сервісів, час відповіді сервера та стан приватних мереж.
Усі важливі сповіщення та звіти про стан інфраструктури BetterStack миттєво надсилає у спеціальний технічний канал Slack. Ми бачимо будь-які відхилення або стрибки навантаження в ту ж секунду, коли вони відбуваються. Це дає нам можливість реагувати на потенційні проблеми проактивно, до того як сайт почне гальмувати у покупців.
Що перевіряти далі після такої міграції
Навіть за умови крутого результату, роботу ми не кидаємо. Зараз ми продовжуємо моніторити систему за кількома технічними точками.
Ми стежимо за показником hit rate у Redis, перевіряємо обсяг вільної пам'яті та дивимося, скільки ключів вилітає по LFU. Також на контролі тримаємо навантаження на MySQL та черги в RabbitMQ під час денних піків трафіку. Нормальна оптимізація - це завжди процес, де спочатку йде стабілізація, потім кеш, а далі - точкове допрацювання вузьких місць.
Висновок
Цей кейс наочно показує: міграція інфраструктури - це далеко не просто копіювання файлів та баз. Справжня робота починається після натискання кнопки «Start».
Тільки через повну перевірку внутрішніх DSN, ліквідацію старих прив'язок до localhost, закриття дірок у безпеці та пошук правильної кеш-стратегії можна отримати реальний результат. У нашому випадку локальний Redis на веб-сервері та гнучке налаштування шарів захисту дозволили проєкту полетіти у 5 разів швидше, працюючи стабільно та передбачувано для бізнесу.