Разработка приложения на Laravel — это одно, а его успешное развертывание и поддержка в высоконагруженной производственной среде — совсем другое. В этом кейсе мы рассмотрим реальный опыт подготовки и запуска SaaS-платформы для управления проектами, построенной на Laravel, с аудиторией в десятки тысяч активных пользователей. Мы пройдем через все этапы: от планирования инфраструктуры и настройки производительности до мониторинга и отказоустойчивости.
Проект представлял собой монолитное Laravel-приложение с классической архитектурой: фронтенд на Blade с живыми компонентами (Livewire), бэкенд на Laravel 9, база данных MySQL (сначала Aurora на AWS), кэширование в Redis (ElastiCache) и очередь задач на Horizon с драйвером Redis. Изначальное развертывание на shared-хостинге быстро показало свою несостоятельность при росте нагрузки. Было принято решение о миграции в облако AWS.
Первый критический шаг — выбор и настройка инфраструктуры. Мы остановились на Elastic Beanstalk для основного приложения, чтобы упростить масштабирование и развертывание. Однако для полного контроля позже перешли на EC2-инстансы, управляемые через Laravel Forge. Были использованы инстансы типа t3.large (2 vCPU, 8 ГБ RAM) с балансировщиком нагрузки (Application Load Balancer) перед несколькими экземплярами приложения. База данных была выделена на отдельный мощный RDS-инстанс (db.r5.large). Redis для кэша и очередей работал на ElastiCache (cache.t3.medium).
Настройка производительности Laravel началась с оптимизации загрузки. Команда `php artisan optimize` была добавлена в скрипт деплоя. Более важным стало использование OpCache (opcache.enable=1, opcache.memory_consumption=256) и JIT-компилятора в PHP 8.1. Конфигурация Nginx была тщательно отточена: включено кэширование статики, gzip-сжатие, правильная обработка заголовков. Для файлов сессий и логов был настроен драйвер `redis` вместо `file`, чтобы избежать проблем при работе нескольких воркеров.
Работа с базой данных — часто самое узкое место. Мы реализовали несколько стратегий. Во-первых, агрессивное кэширование с помощью `Cache::remember()` для тяжелых запросов, которые не требуют мгновенной актуальности (списки проектов, отчеты). Во-вторых, была проведена индексация: с помощью Laravel Debugbar и прямых EXPLAIN-запросов мы выявили и добавили недостающие индексы для `WHERE`, `JOIN` и `ORDER BY`. В-третьих, для чтения использовались реплики. Мы настроили конфигурацию базы данных в `config/database.php` для разделения чтения и записи.
'mysql' => [
'read' => [
'host' => [
env('DB_READ_HOST_1', 'replica1.example.com'),
env('DB_READ_HOST_2', 'replica2.example.com'),
],
],
'write' => [
'host' => env('DB_WRITE_HOST', 'primary.example.com'),
],
'sticky' => true, // Важно для согласованности данных в рамках запроса
// ... остальные параметры
],
Очереди стали нашим спасением для фоновых задач. Все тяжелые операции — отправка email-рассылок, генерация PDF-отчетов, обработка загруженных файлов — были перенесены в jobs. Horizon был настроен с несколькими супервизорами для разных типов задач: `default` для быстрых, `emails` для рассылок, `reports` для длительных. Мониторинг Horizon через его dashboard был незаменим.
Безопасность в продакшене — это must. Мы использовали все встроенные средства Laravel: `php artisan down --secret="..."` для скрытого режима обслуживания, хеширование cookies, защиту от CSRF. Все чувствительные данные (ключи API, пароли БД) хранились в AWS Secrets Manager, а Laravel получал их через кастомный провайдер конфигурации на этапе загрузки. Для защиты от DDoS и ботов перед ALB был установлен AWS WAF с базовыми правилами.
Мониторинг и логирование. Мы отказались от хранения логов на диске инстансов. Вместо этого настроили отправку логов Laravel (через канал `stack`) в CloudWatch Logs. Для мониторинга производительности применили Laravel Telescope в продакшене, но с ограниченным доступом только по IP-адресам администраторов. Ключевые бизнес-метрики (количество регистраций, успешных операций) отправлялись в Amazon CloudWatch Metrics с помощью пакета. Это позволяло строить дашборды и настраивать алерты.
Процесс непрерывной интеграции и доставки (CI/CD) был построен на GitHub Actions. При пуше в ветку `main` автоматически запускались тесты (PHPUnit, Pest), статический анализ кода (Laravel Pint, PHPStan), сборка фронтенда (Vite), и в случае успеха — деплой на продакшен-серверы через Forge API. Миграции базы данных выполнялись автоматически, но с обязательным созданием резервной копии RDS snapshot перед этим.
Одной из самых больших проблем стала работа с файловыми загрузками пользователей. Изначально файлы хранились на локальном диске EC2, что создавало проблемы при масштабировании. Решение — переход на Amazon S3 с использованием драйвера `s3` в Laravel Filesystem. Это обеспечило отказоустойчивость и возможность раздачи файлов через CloudFront CDN для ускорения загрузки по всему миру.
Кэширование конфигурации, маршрутов и представлений (`php artisan config:cache`, `route:cache`, `view:cache`) стало обязательным этапом деплоя. Однако это создавало сложности при разработке, так как требовало очистки кэша после любых изменений. Мы автоматизировали очистку кэша Redis при деплое с помощью скрипта в Forge.
В итоге, приложение стабильно обрабатывало пиковые нагрузки до 5000 одновременных пользователей. Среднее время ответа сервера составляло менее 200 мс. Ключевыми выводами стали: не экономить на инфраструктуре с самого начала, использовать очереди для всего, что можно отложить, инвестировать время в настройку мониторинга и обязательно иметь план аварийного восстановления (backup RDS, snapshots EC2). Laravel в связке с правильной облачной инфраструктурой доказал свою способность работать в высоконагруженном продакшене.
Кейс: Развертывание высоконагруженного приложения на Laravel в продакшене
Реальный кейс развертывания и оптимизации высоконагруженного SaaS-приложения на Laravel в облачной инфраструктуре AWS. Рассматриваются вопросы архитектуры, производительности (кэширование, базы данных, очереди), безопасности, мониторинга и CI/CD.
2
3
Комментарии (13)