HTTP의 핵심 특성인 Stateless를 이해하려면, 먼저 로그인 시나리오를 통해 서버가 사용자 상태를 어떻게(혹은 어떻게 하지 않는지) 관리하는지 살펴보자.
데이터베이스 예시)
| id | user_name | user_id | user_pw |
|---|---|---|---|
| 0 | a | xxx | 1234 |
| 1 | b | yyy | 1234 |
신대방에서 사용자가 로그인 시도 → POST 요청으로 id, 비밀번호 전송 → 서버에서 DB 조회 → 일치 시 "로그인 성공" 메시지 반환.
핵심 질문: 로그인 성공 후, "이 사용자가 로그인한 상태"라는 정보를 어디에 저장해야 할까?
서버 메모리: { IP: "xxx.xxx.xxx", userId: "xxx", loggedIn: true }
문제점:
클라이언트 브라우저: 인증토큰 "abc123xyz789"
동작 방식:
1. 로그인 성공 → 서버가 난수값(토큰) 발급
2. 브라우저가 요청할 때마다 이 토큰을 Header에 포함
3. 서버는 토큰만 검증 → 유효하면 "로그인 상태"로 처리
4. 서버는 사용자 상태를 기억하지 않음 → Stateless
장점:
[사용자 A] ──→ [Load Balancer] ──→ [서버1] (A 로그인 → 세션 저장)
│
└──→ [서버2] (세션 없음 → 재로그인 필요!)
서버 증설 시 문제:
[사용자 A] ──→ [Load Balancer] ──→ [어느 서버든 상관없음]
│
│ (토큰만 검증하면 됨)
└──→ [서버1/서버2/서버N]
확장성 완벽:
| 특성 | Stateful | Stateless |
|---|---|---|
| 연결성 | 연결 지향 | 비연결성 지향 |
| 프로토콜 | TCP/IP | HTTP |
| 연결 유지 | 3-Way Handshake 후 지속적 연결 | 요청→응답 후 연결 끊기 |
| 서버 상태 | 사용자 정보 메모리 저장 | 토큰만 검증 |
| 확장성 | 서버별 세션 관리 → 제한적 | 모든 서버 동일 로직 → 완벽 |
TCP (연결지향):
1. 3-Way Handshake (연결맺기)
2. 데이터 전송
3. 연결 **유지**
4. 계속 메시지 주고받음
HTTP (비연결성):
1. 3-Way Handshake (TCP 기반)
2. HTTP 요청→응답
3. 연결 **끊기**
4. 다음 요청 시 **재연결**
성능 비교:
TCP: 매번 3-Way Handshake → 느림
HTTP: 연결 끊고 간헐적 요청 → 빠름 + 서버 부하↓
HTTP의 한계: 서버가 클라이언트에게 자발적 푸시 불가
HTTP: 클라이언트 → 서버 요청 → 서버 응답 (단방향)
WebSocket: 양방향 지속 연결 (채팅, 실시간 알림)
일반 웹페이지:
- 새로고침 안 하면 → 서버는 **사용자 접속 모름**
- 서버 부하 **없음**
채팅앱 (디스코드):
- 아무것도 안 해도 → **지속 연결 유지**
- 서버가 사용자 위치를 **항상 알고 있음**
- 인터넷 끊기면 **즉시 연결해제**
대부분 웹서비스: HTTP + Stateless (토큰)
- 빠른 응답
- 서버 확장성
- 메모리 효율성
실시간 서비스: WebSocket + Stateful
- 양방향 통신
- 지속 연결
- 사용자 위치 추적
정리:
1. Stateless = 서버가 사용자 상태 기억 X → 토큰으로 검증
2. Stateful = 서버가 사용자 상태 기억 → 메모리 부하 + 확장성 문제
3. HTTP는 기본 Stateless, 실시간은 WebSocket