Як я планую масштабувати свій додаток на Laravel (PHP)

pic

Я будую 10MPage.com, що захоплює стан інтернету у 2025 році. Кожен користувач інтернету може завантажити мале зображення розміром 64x64 пікселів і долучитися до цього архіву. Це стосується і вас! 😉

Як одиничний розробник, я хочу витрачати якомога менше грошей на початкових етапах цього проекту, тому я розміщую його на дешевому VPS.
Але я хочу бути готовим до того, що буде далі, коли цей проект розростеться, і мені потрібно мати план для масштабування хостингу цього застосунку.

Застосунок написаний на PHP з використанням фреймворку Laravel і наразі розміщений на одному сервері. Застосунок сильно залежить від фонових процесів для обробки зображень, пошуку вільних місць на сітці для розміщення нових зображень та відправки електронних листів.

Фонові процеси виконуються через Laravel Horizon, який є системою черг, що використовує довготривалий PHP процес. Цей процес працює через supervisor для забезпечення його автоматичного перезапуску після зупинки. При кожному розгортанні застосунку процес зупиняється і перезапускається supervisor.

Усі завдання та кешування виконуються за допомогою Redis, а дані зберігаються в базі даних MySQL. Веб-запити обробляються через nginx з використанням PHP-FPM.
Поточна конфігурація виглядає так:

pic

Я розумію, що є сервіси, як Laravel Forge, але вони вимагають додаткової підписки, що коштує більше, ніж ціна мого одного сервера. Саме тому я налаштовую все самостійно на простому VPS.

Перший і найпростіший спосіб масштабування — це оновлення VPS до більшого сервера. Це можна зробити за кілька хвилин, і при цьому буде невеликий перерви в роботі. Але це хороший спосіб купити час, якщо масштабування необхідне через високе навантаження, щоб налаштувати інші сервери.

Для подальшого масштабування мені потрібні окремі сервери. Я б хотів зробити це з мінімальним часом простою, ось мій план у (count) кроках:

  1. Перемістити Redis на окремий сервер
  2. Додати балансувальник навантаження
  3. Створити нові сервери для обробників
  4. Додати веб-сервери
  5. Старий веб-сервер стає новим сервером бази даних

Крок перший, Redis

Час простою: відсутній

Я б почав з переміщення Redis на інший сервер. Веб-застосунок можна налаштувати для тимчасового використання локальної файлової системи для кешування, а чергу завдань можна тимчасово вимкнути. Я б налаштував новий сервер і додав його до приватної мережі. Я не займався б кластеризацією Redis, оскільки Laravel Horizon не підтримує кластери Redis.
Після переміщення Redis, ми можемо вимкнути його і видалити з оригінального сервера.

На цьому етапі у мене буде два сервери: один для Redis і один для веб/бази даних/обробників, які обробляють решту.

pic

Крок другий, балансувальник навантаження

Час простою: відсутній

Для балансування навантаження між кількома веб-серверами нам спочатку потрібен балансувальник навантаження. Я маю досвід роботи з HAProxy, тому використаю саме його. Він має більше можливостей для балансування навантаження, таких як активна перевірка працездатності та більше алгоритмів навантаження.
Цей сервер також буде обробляти SSL-термінацію.

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

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

pic

Крок третій, окремі сервери обробників

Час простою: відсутній

Як я вже пояснював, фонові обробники є важливими для запуску цього проекту. Вони повинні взаємодіяти з Redis і базою даних, щоб виконувати свою роботу, і можуть бути вимкнені на деякий час. Застосунок спроектований таким чином, що він завжди починає з того місця, де він був останній раз зупинений.
Це реалізується за допомогою станів, наприклад, плитка зі статусом «place» вказує робітнику, що її потрібно помістити. Після цього статус змінюється.

Laravel Horizon також розроблений для роботи на кількох серверах, що означає, що мені не потрібно зупиняти поточного робітника при додаванні нового. Процес перенесення цього на інший сервер є простим. Ми створюємо новий сервер, розгортаємо та налаштовуємо застосунок і використовуємо supervisor для запуску робітника.

Після цього ми можемо вимкнути робітника на оригінальному сервері. Масштабування робітників таке ж просте, як просто створення копії робітника.

pic

Крок четвертий, кілька веб-серверів

Час простою: відсутній

Ми вже додали балансувальник навантаження, щоб відокремити веб-сервери, ми можемо виконати ті ж самі кроки, як і для робітників. Але замість того, щоб запускати Horizon через supervisor, сервер буде обслуговувати застосунок через HTTP за допомогою nginx і FPM. Тут, як і раніше, при наявності одного сервера ми можемо просто створити його копію. Єдине, що потрібно налаштувати — це додати веб-сервери до балансувальника навантаження.

На цьому етапі конфігурація виглядає так: один сервер Redis, один сервер бази даних, один балансувальник навантаження, окремі сервери робітників і окремі веб-сервери.

pic

Крок п'ятий, один сервер бази даних

Час простою: кілька хвилин

Оригінальний сервер тепер має лише одну функцію — базу даних. Для того, щоб зберегти його чистим, я видалю все інше, що не потрібне на цьому сервері. Nginx, supervisor, redis і PHP можуть бути видалені. Оскільки сервер бази даних є однією з найважливіших частин застосунку, я потребую, щоб він мав достатню потужність. Кластери — це варіант, але також багато роботи. Я думаю, що одного великого сервера бази даних буде достатньо для цього проекту, але це має свою вартість. Масштабування потребуватиме перезавантаження сервера, під час якого застосунок не працюватиме.

Отже, це всі п'ять кроків мого плану масштабування для 10MPage. Ось всі етапи візуалізовані:

pic

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

Я використовую розгортання на основі git, у мене є невеликий скрипт, що включено в репозиторій, який розгортає застосунок. Для одного сервера він виконує всі кроки, але для окремих серверів йому потрібно перевірити, що саме слід розгорнути. Наприклад, я можу виконати команду php artisan horizon:status, щоб перевірити, чи працює Horizon, і перезапустити його лише тоді, коли він працює. Те ж саме я можу зробити і для PHP-FPM.

Єдине коригування полягає в тому, що потрібно запускати на кількох серверах. Я створю простий скрипт, який активує це на всіх серверах.

Я усвідомлюю, що ця конфігурація має кілька точок відмови.
Точки відмови:

  • Один балансувальник навантаження
  • Один сервер бази даних
  • Один сервер Redis

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

Сервери бази даних і Redis — це інша історія, якщо мені потрібно буде їх масштабувати, я напишу наступну статтю про це. Але я не очікую, що це станеться.

Я великий прихильник запуску застосунків у контейнерах, і їх масштабованість справді чудова. Але для менших проектів, як цей, я вважаю, що контейнеризація застосунку та його розгортання на кластері — це надмірність. Я залишаю налаштування хостингу простими, щоб швидко налаштувати на початковому етапі проекту. Я не бачу потреби в таких речах, як автоматичне масштабування. Єдина причина використання контейнерів у цьому проекті полягає в легкості налаштування при масштабуванні на кілька серверів.
Але оскільки цей проект не вимагає багато ресурсів, я вирішив, що краще створювати знімки та клонувати машини, коли потрібно буде масштабувати

Масштабування 10MPage.com є захоплюючим викликом, до якого я підходжу з прагматичним мисленням, зберігаючи інфраструктуру простою та ефективною. Починаючи з мінімальної конфігурації на одному VPS, я забезпечую економію витрат на ранніх етапах, в той час як намічений план масштабування гарантує плавний перехід у міру зростання проекту. Кожен крок — від переміщення Redis на окремий сервер до впровадження балансувальника навантаження, додавання робітників і розгортання кількох веб-серверів — спроектовано таким чином, щоб мінімізувати час простою і підтримувати функціональність додатку.

Зберігаючи хостинг простим і уникаючи складнощів контейнеризації чи кластерів, я можу зосередитись на розробці проекту і адаптації до змінюваних вимог. Такий обдуманий підхід балансує підготовку і простоту, забезпечуючи, щоб 10MPage.com залишався надійним, масштабованим і відповідав своїй місії — захопити суть інтернету 2025 року — одну плитку за раз.

Дякую за прочитану статтю, сподіваюся, що ви дізналися щось нове.
Якщо так, чому б не додати свою улюблену мову програмування, криптовалюту чи домашнього улюбленця на 10MPage? Це безкоштовно!

Перекладено з: How I plan on scaling my Laravel (PHP) application

Leave a Reply

Your email address will not be published. Required fields are marked *