В чём разница между Stateless и Stateful приложениями?
Stateless (без состояния) – приложение не хранит состояние клиента между запросами; каждый запрос содержит всю необходимую информацию для обработки. Stateful (с состоянием) – приложение хранит состояние клиента (сессию) в памяти между запросами; последующие запросы должны попадать на тот же сервер. Это как разница между кассой самообслуживания (каждый раз показываешь карту лояльности) и персональным менеджером (который помнит тебя в лицо).
Схема работы
Пример
Stateless:
Запрос 1 (token + данные) → Сервер A → Ответ
Запрос 2 (token + данные) → Сервер B → Ответ (любой сервер)
Запрос 3 (token + данные) → Сервер C → Ответ
Stateful:
Запрос 1 → Сервер A (создаёт сессию) → Ответ (session_id)
Запрос 2 (session_id) → Сервер A → Ответ (ТОЛЬКО Сервер A!)
Запрос 3 (session_id) → Сервер A → Ответ
Сравнение
| Аспект | Stateless | Stateful |
|---|---|---|
| Состояние | Не хранится на сервере | Хранится в памяти сервера |
| Масштабирование | Простое (любой узел) | Сложное (sticky sessions или репликация) |
| Отказоустойчивость | Высокая | Потеря сессии при падении узла |
| Производительность | Каждый запрос содержит полный контекст | Меньше передаваемых данных (сессия на сервере) |
| Пример | REST API + JWT | Servlet с HttpSession |
Как сделать приложение Stateless
- Аутентификация через JWT-токены – вся информация о пользователе внутри токена.
- Хранение сессий во внешнем хранилище (Redis) – Spring Session позволяет вынести сессию из памяти JVM.
- Хранение состояния на стороне клиента (cookie, localStorage).
Пример
// Stateless: JWT содержит всю информацию
@GetMapping("/api/profile")
public ResponseEntity<ProfileDto> getProfile(
@AuthenticationPrincipal JwtUser user) {
// user уже извлечён из токена, не нужна серверная сессия
return ResponseEntity.ok(profileService.getProfile(user.getId()));
}
Итог
Stateless-подход предпочтителен для backend-сервисов (REST API на Spring Boot + JWT/OAuth2), так как упрощает горизонтальное масштабирование и развёртывание в Kubernetes. Если приложению нужно серверное состояние (например, WebSocket-соединения), его выносят во внешнее хранилище (Redis, Hazelcast), чтобы сервер оставался заменяемым.
На собеседовании: Интервьюер ожидает понимания влияния на масштабирование и знания способов вынесения состояния. Частая ошибка – утверждать, что stateless-приложение вообще не имеет состояния, тогда как состояние просто перемещается (в токен, Redis, клиент).