Застосунок без стану (stateless) - будь-який запит може обробити будь-який сервер, бо жоден сервер не зберігає даних, потрібних для наступних запитів. Тоді балансувальник може розподіляти запити довільно, а сервери - додавати, прибирати й перезапускати без втрати даних.
Що зазвичай «прилипає» до сервера в Laravel-застосунку:
1. Сесії. Драйвер file зберігає сесії на локальному диску. Запит на інший сервер - користувач «розлогінений».
Рішення: SESSION_DRIVER=redis чи database.
2. Завантажені файли. Storage::disk('local') пише на диск конкретного сервера - файл, завантажений на сервер A, недоступний на сервері B.
Рішення: спільне сховище - S3, R2, MinIO (FILESYSTEM_DISK=s3).
3. Кеш. Драйвер file чи array - у кожного сервера свій кеш: інвалідація на одному не діє на інших, а атомарні блокування (Cache::lock) не працюють між серверами.
Рішення: CACHE_STORE=redis.
4. Черги. Драйвер sync виконує задачі в запиті; database - працює, але під навантаженням краще Redis чи SQS.
5. Планувальник. schedule:run на кожному сервері запустить задачу N разів.
Рішення: ->onOneServer() (потребує спільного кешу для блокування) або окремий сервер для планувальника.
6. Локальні змінні середовища й файли конфігурації - однакові на всіх серверах, деплой з одного артефакту (Docker-образ).
7. Ліміти частоти (throttle) - лічильники в кеші: з локальним кешем кожен сервер рахує окремо, і реальний ліміт множиться на кількість серверів.
«Липкі сесії» (sticky sessions) на балансувальнику - обхідний шлях: користувача завжди відправляють на той самий сервер. Працює, але сервер стає точкою відмови для своїх користувачів, а навантаження розподіляється нерівномірно.
Перевірка готовності: запустити два екземпляри за балансувальником і пройти основні сценарії - вхід, завантаження файлу, черги, кеш. Те, що зламається, і є прихованим станом.