Розробка бекенду на PHP Laravel: оптимізація та масштабування

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

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка бекенду на PHP Laravel: оптимізація та масштабування
Середній
від 1 тижня до 3 місяців
Часті запитання

Розробка бекенду Laravel: де проєкт ламається на зростанні

Розробка бекенду Laravel рідко ламається в момент запуску — перші симптоми з'являються, коли зростання кількості звернень перестає бути лінійним. Окремі сторінки починають відповідати повільніше, далі час відповіді під навантаженням стрибає на піках, і кеш уже не маскує проблему.

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

Найчастіша причина — важкі запити до бази: вибірки без індексів, звернення всередині циклів замість пакетного завантаження зв'язків, агрегати по всій таблиці на кожен показ сторінки.

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

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

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

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

Що змінюється після переробки: вимірювані ефекти

Скорочення часу відповіді

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

Заміри знімаємо до і після на тому самому профілі навантаження — на Laravel видно, де час іде в запити, а де в проміжні шари. Час відповіді типових сторінок скорочується в рази, а не на відсотки, і це фіксується графіками у звіті.

Передбачуваність на піках і обробка черг

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

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

Зникнення класу відмов через деградацію бази

Основна причина падінь — не помилка в коді, а перевантажена база: з'єднання закінчуються, запити чекають і падають за таймаутом. Ми обмежуємо пул з'єднань, розводимо читання й запис, ставимо таймаути й повтори на ідемпотентні операції, а важкі звіти переносимо на окремий контур.

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

Формати робіт: оптимізація, переписування, винесення сервісів

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

Варіант Коли підходить Обмеження
Оптимізація наявного коду Уповільнення точкове: важкі вибірки, дублі запитів, немає кешу Не рятує, якщо впирається в загальний розділюваний ресурс
Переписування шару доступу до даних Логіка вибірок розповзлася по контролерах, моделі розрослися Потрібні тести до початку робіт, інакше немає безпечного відкату
Винесення навантаженого модуля в окремий сервіс Одна ділянка тримає трафік і потребує власного масштабування З'являється мережева взаємодія, окремі збірка й спостережуваність

Оптимізація коду та шар доступу до даних

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

Коли доступ до даних розмазаний по контролерах і моделях, дешевше переписати шар доступу до даних: зібрати вибірки в репозиторії, привести запити до єдиного вигляду й покрити тестами.

Це більше роботи, зате наступний виток навантаження вже не потребуватиме переписування логіки заново.

Винесення модуля й рефакторинг без зупинки

Винесення навантаженого модуля виправдане, коли ділянка потребує власного масштабування й свого циклу випуску. Плата — ускладнення експлуатації: мережеві виклики, окремі збірка, логи й розгортання, обробка часткових відмов.

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

Етапи робіт: від аудиту вузьких місць до передачі команді

Роботи починаються не з переписування, а із заміру. Поки немає цифр «до», будь-яка зміна — питання віри: спочатку фіксуємо стан системи, потім чіпаємо код.

  1. Аудит кодової бази Laravel. Дубльовані запити, звернення до бази всередині циклів, відсутні індекси та місця, де з'єднання тримається довше, ніж потрібно.
  2. Зняття метрик продуктивності. Профілюємо ключові сценарії: час відповіді, кількість запитів на операцію, споживання пам'яті, частка часу в базі та зовнішніх сервісах. Це база для порівняння «до» і «після».
  3. Схема взаємодії. Застосунок, кеш, черга, база та зовнішні сервіси на одній схемі — видно, де втрачається час і відмова якого вузла тягне за собою решту.
  4. План змін. Пріоритети за співвідношенням ефекту й ризику: спочатку правки, що дають виграш без переписування, потім структурні.
  5. Зміна конфігурації та точкова оптимізація. Пул з'єднань, індекси, кешування повторюваних обчислень, винесення важких операцій у фонову чергу.
  6. Перевірка на навантаженні. Повторний прогін тих самих сценаріїв із тими самими метриками, порівняння результатів і поведінка системи за відмови окремого вузла.
  7. Передача команді. Документація, регламент викочування, дашборди метрик і розбір із вашими інженерами — система залишається керованою й без нас.

Артефакти проєкту: схеми даних, регламенти, документація

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

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

  • Схема сервісів — які процеси піднімаються, як проходять запити, де стоять кеш, черга й база, від яких зовнішніх постачальників залежить застосунок і в якому порядку середовище збирається з нуля.
  • Схема даних — таблиці, зв'язки, індекси та усвідомлені денормалізації з поясненням, навіщо вони зроблені; поруч міграції, за якими видно перехід бази на кожному релізі.
  • Опис черг — які завдання йдуть у фон, скільки спроб і з яким інтервалом їм дається, де потрібна ідемпотентність, як знайти зависле завдання й безпечно перезапустити його.
  • Правила доступу — ролі та права в інтерфейсі адміністратора й програмному інтерфейсі, де зберігаються ключі, як вони змінюються, хто і за якою процедурою отримує доступ до робочого контуру.
  • Регламент викладки — порядок збірки релізу, прогін міграцій, прогрів кешу, перевірки після випуску й покроковий відкат на попередню версію, якщо поведінка розійшлася з очікуваною.
  • Документація з підтримки — типові відмови та їхні симптоми, які метрики й журнали дивитися першими, на які оповіщення реагувати одразу, а які розбирати в робочий час.

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

Кейс: Laravel-проєкт під зростаючим навантаженням, метрики до і після

Проєкт — сервіс обробки замовлень: Laravel за зворотним проксі, база й черга в окремих контурах. На піку до 900 одночасних звернень час відповіді виріс з 0,4 до 3,5 секунди, частка помилкових запитів дійшла до 12%, а падіння обробників черги давали до 40 хвилин простою на добу. Частина задач вмирала за таймаутом, клієнти бачили порожні списки замість історії замовлень.

Профілювання показало три вузькі місця. На одну картку замовлення йшло до 300 запитів до бази — пов'язані сутності тягнулися по одному. Звіти й розсилки рахувалися синхронно в тому самому процесі, що й веб-запити, і блокували прийом нових замовлень. Кеш конфігурації та маршрутів не збирався, кожен запит заново розбирав файли.

Що змінили в коді та конфігурації

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

Застосунок запустили в кількох екземплярах, сесії та кеш винесли в спільне сховище, статику — на зовнішній шар віддачі.

Через місяць на тому самому профілі піку: час відповіді — 0,3 секунди, частка помилок — 0,4%, позаплановий простій — нуль, вікно планових робіт — кілька хвилин. Контур витримав триразове зростання одночасних звернень без нових серверів, а масштабування далі йшло без правок коду.

Чим відрізняється кешування в застосунку від кешування в базі?

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

Рівень Що зберігає Коли дає ефект Коли шкодить
Кеш застосунку Готові результати обчислень Важкі агрегати, повторні читання, зовнішні виклики Кілька інстансів із різними даними; часті правки записів
Кеш на боці бази Плани запитів, представлення, індекси Однотипні часті читання Транзакційний запис: обслуговування дорожче за сам запит

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

Вибір рівня кешування диктує профіль навантаження. Якщо час іде на обчислення та збірку відповіді — кешуємо в застосунку: у Laravel це окремий шар поверх сховища.

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

Технічні сумніви: черги, міграції, регрес

Сумніви зазвичай спливають на етапі передачі проєкту або першого релізу. П'ять питань, які ставлять найчастіше, з короткими практичними відповідями.

Довгі розсилки й вивантаження блокують інтерфейс?

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

Чи можна оновлювати схему бази без зупинки сервісу?

Так. Міграції йдуть безпечними кроками: спочатку нові поля та індекси, потім перенесення даних порціями й лише потім перемикання читання й запису. Стара версія застосунку працює весь цей час.

Як переконатися, що доопрацювання не зламало робоче?

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

Хто має доступ до бази та персональних даних?

Доступ видається за ролями й лише під поточну задачу, кожне підключення потрапляє в журнал. Чутливі поля шифруються, копії зберігаються окремо й регулярно перевіряються відновленням.

Що як у нас немає власної команди розробки?

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

Нижче — решта питань, які варто закрити до старту робіт.

Обговоримо вашу задачу: з чого почнемо і що знадобиться

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

Що надіслати для оцінки:

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

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

Опишіть задачу — повернемося з оцінкою та планом.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060