HTTP는 TCP 기반으로 통신하는데 TCP는 stateful이고 HTTP는 Stateless이다?
이해가 안됨
- TCP는 stateful, HTTP는 TCP 기반으로 통신, 하지만 HTTP는 Stateless
다시말해 TCP는 연결 지향형이고 상태 저장적인 프로토콜인데, 왜 HTTP는 반대로 상태 비저장인가?
확인한 내용
HTTP 요청 → TCP 연결 설정 (3-Way Handshake) → 데이터 전송 → TCP 연결 종료
HTTP는 TCP 위에서 동작하지만, HTTP 자체는 상태를 유지하지 않음
다시말해 TCP는 연결을 맺고 데이터를 보장하지만, HTTP 요청 자체는 독립적으로 처리한다는 것
-> HTTP는 "TCP를 활용하는 Stateless 프로토콜"
실제 과정 예시(과정 통해 이해완료)
1. 7계층에서 사용자가 웹 브라우저에서 http://example.com/index.html을 입력하면, HTTP 요청이 생성됨.
(이때 DNS 조회 이뤄지며, 이 요청은 전송되지 않은 상태) 이 때 해당 패킷은 4계층으로 이동후 대기
2. 4계층에서 HTTP 요청이 전송되기 위해 TCP 연결이 먼저 설정되어야 함. 이때 3way handshake 이뤄짐.
2-1. 서버로 SYN 패킷을 보낼 준비를 하는데, 이때 TCP 헤더에 출발지 포트, 목적지 포트등 정보가 포함됨
3. 3계층에서 SYN패킷에 IP헤더가 추가됨.
4. 2계층에서 ARP로 획득된 Next hop MAC어드레스와 출발지 맥어드레스가 담긴 이더넷 헤더가 추가됨.
5. 1계층에서 발송
위 과정 이후 SYN-ACK을 수신받고, ACK패킷을 전송하여 TCP 연결을 확립.
이 3단계 (3-way handshake) 과정을 모두 완료해야 비로소 TCP 연결이 "Established (확립)" 상태가 됨.
TCP 연결이 완전히 맺어진 후에 응용 계층에서 생성된 HTTP 요청 패킷을 전송가능.
HTTP가 TCP 기반으로 만들어진 이유
HTTP는 웹 페이지, 이미지, 영상 등 중요한 웹 정보를 주고받아야함. 데이터가 손실되거나 깨지면 웹 페이지가 제대로 표시되지 않거나 오류가 발생. 또한 데이터가 순서대 정확히 전달되어야 함.파일 조각이 순서 없이 뒤죽박죽 도착하면 안 됨.
TCP는 연결지향적이고, 신뢰성있는 연결 보장하고, 순서도 보장하고, 상태 저장적임.
정리하자면 TCP는 저런 특성을 가지고 서로 통신할수있도록 연결하고, 그 연결된 상태에서 HTTP는 stateless로 활동한다는 것
그렇다면 Stateless가 아니라면?
서버 자원 소모 증가 (메모리, CPU):
- 각 클라이언트 상태 정보 저장: 서버는 모든 활성 사용자들의 상태 정보를 메모리에 저장해야 합니다. 사용자 수가 늘어날수록 서버 메모리 사용량은 기하급수적으로 증가합니다.
- 상태 정보 유지 및 갱신: 상태 정보를 계속해서 최신 상태로 유지하고, 사용자의 행동에 따라 갱신해야 합니다. 이 과정에서 서버 CPU 자원이 지속적으로 소모됩니다.
- 세션 관리 오버헤드: 세션 시작, 유지, 만료, 세션 정보 동기화 등 세션 관리 자체에 많은 서버 자원이 소모됩니다.
확장성 (Scalability) 제한:
- 수평 확장 (Horizontal Scaling) 어려움: 사용자 증가에 따라 서버를 늘리는 수평 확장이 매우 어려워집니다. 각 서버가 모든 클라이언트의 상태 정보를 공유해야 하므로, 서버 간 상태 동기화, 세션 클러스터링 등 복잡한 기술이 필요합니다. 서버 증설 시 비용과 복잡도가 크게 증가합니다.
- 특정 서버 의존성 증가: 특정 클라이언트의 상태 정보가 특정 서버에만 저장되어 있다면, 해당 서버에 장애가 발생했을 때 서비스 전체에 영향을 줄 수 있습니다. 특정 서버에 대한 의존성이 높아져 안정성이 저하됩니다.
- 로드 밸런싱 (Load Balancing) 비효율: 로드 밸런서가 요청을 분산할 때, 상태 정보가 저장된 특정 서버로만 요청을 보내야 할 수 있습니다. 로드 밸런싱 효율성이 떨어지고, 특정 서버에 부하가 집중될 수 있습니다.
자꾸 보였던 기타 내용
* HTTP Keep-Alive
HTTP Client와 Server(Web Server) 사이에서 동일한 TCP Connection을 이용해서 여러번 요청을 보내기 위해서 사용.
여러 요청을 하나의 TCP Connection에서 진행하기 때문에 TCP 연결을 위한 3-way Handshake는 첫번째 이후 새롭게 맺지 않음. 이를 통해 2번째부터는 latency 가 줄어들고 서버 리소스적인 부하도 적어짐
-> HTTP의 stateless 성격때문에 데이터 주고받을때마다 TCP 연결 해야하면 부하가 커지니까 한번 TCP 연결이 되었을때 처리하라는 것
* TCP Keep-Alive
TCP KeepAlive는 TCP 연결이 맺어진 이후 해당 연결을 유지하는 것에 대해서 작은 패킷을 보내며 체크하는 매너커즘을 말합니다. 해당 KeepAlive Packet을 통해서 지속적으로 연결이 되어있는지 체크도 하며 만약 Connection이 끊어졌다면 즉시 끊어졌다고 알려주는 역할까지 합니다. 만약 KeepAlive가 없다면 다음 실제 Packet이 전달되기 전 까지 연결이 정상인지 아닌지 알 수 없습니다.