테마
03. HTTP 핵심 특성
HTTP를 단순히 “요청과 응답을 주고받는 규칙”으로만 보면, 왜 이 프로토콜이 웹 전체의 기본이 되었는지 이해하기 어렵다.
HTTP의 핵심은 클라이언트와 서버를 분리하고, 요청을 가능한 한 자기완결적으로 만들며, 연결 자원을 오래 붙잡지 않는 쪽으로 설계되어 있다는 점이다.
이 장을 읽고 나면
- HTTP의 클라이언트-서버 구조가 왜 중요한지 설명할 수 있다.
- 상태 유지(Stateful)와 무상태(Stateless)의 차이를 구분할 수 있다.
- 무상태 설계가 왜 서버 확장과 장애 대응에 유리한지 이해할 수 있다.
- HTTP의 비연결성이 서버 자원 효율과 어떤 관련이 있는지 설명할 수 있다.
- 지속 연결(Persistent Connection)이 왜 필요한지, 비연결성과 어떻게 함께 이해해야 하는지 설명할 수 있다.
이 장의 지도
Figure 3.1 HTTP 핵심 특성은 역할 분리, 무상태, 비연결성, 지속 연결로 이어집니다.
1. HTTP는 왜 클라이언트와 서버를 분리할까?
HTTP의 가장 단순한 형태는 이것이다.
- 클라이언트가 요청을 보낸다
- 서버가 응답을 만든다
- 클라이언트는 응답을 받아 동작한다
겉으로 보면 너무 단순해 보이지만, HTTP의 진짜 강점은 역할 분리에 있다.
Figure 3.2 HTTP의 기본 단위는 클라이언트의 요청과 서버의 응답입니다.
역할 분리의 핵심
클라이언트는 보통 여기에 집중한다.
- 화면 표시
- 사용자 입력 처리
- 사용성(UI/UX)
서버는 보통 여기에 집중한다.
- 비즈니스 로직
- 데이터 저장과 조회
- 인증, 권한, 트래픽 처리
Figure 3.3 HTTP는 클라이언트와 서버가 각자의 책임을 따로 발전시킬 수 있게 합니다.
왜 이렇게 나누는가?
이렇게 나누면 클라이언트와 서버가 독립적으로 진화할 수 있다.
- 클라이언트는 PC, 모바일, TV처럼 다양한 UI 환경에 맞게 발전할 수 있다.
- 서버는 트래픽 증가에 맞춰 언어, 프레임워크, 아키텍처를 바꿔도 된다.
- 둘은 HTTP라는 공통 약속만 지키면 된다.
| 구분 | 클라이언트 | 서버 |
|---|---|---|
| 주 관심사 | 화면, UX, 입력 처리 | 비즈니스 로직, 데이터, 확장성 |
| 변경 이유 | 디바이스/화면 변화 | 트래픽 증가, 기술 교체, 운영 요구 |
| 독립성 이점 | UI 개선에 집중 가능 | 성능/확장 문제를 별도로 해결 가능 |
핵심 직관: HTTP는 클라이언트와 서버가 서로의 내부 구현을 몰라도 협업할 수 있게 만드는 공통 인터페이스다.
2. 상태 유지와 무상태는 무엇이 다를까?
HTTP를 이해할 때 가장 중요한 개념 중 하나가 무상태(Stateless) 다.
상태 유지(Stateful)
상태 유지란 서버가 클라이언트의 이전 요청 문맥을 기억하는 것이다.
예를 들어 점원과 고객 대화로 생각해 보자.
- 고객: 이 노트북 얼마예요?
- 점원: 100만 원입니다.
- 고객: 그럼 2개 살게요.
- 점원: 200만 원입니다.
- 고객: 카드로 결제할게요.
여기서 마지막 문장인 “카드로 결제할게요”만 보면, 점원이 이전 맥락을 기억해야 무엇을 결제하는지 이해할 수 있다. 이것이 상태 유지다.
무상태(Stateless)
무상태란 서버가 이전 요청을 기억하지 않고, 매 요청이 스스로 완결된 정보를 갖는 것이다.
같은 상황을 무상태로 바꾸면 이렇게 된다.
- 고객: 이 노트북 얼마예요?
- 점원: 100만 원입니다.
- 고객: 노트북 2개를 구매하겠습니다.
- 점원: 200만 원입니다.
- 고객: 노트북 2개를 신용카드로 구매하겠습니다.
마지막 요청만 봐도 결제에 필요한 정보가 충분하다.
Figure 3.4 상태 유지 요청은 이전 문맥에 기대고, 무상태 요청은 필요한 정보를 요청 안에 담습니다.
HTTP가 무상태를 지향하는 이유
무상태가 중요한 이유는 요청을 처리하는 서버가 매번 바뀌어도 괜찮아지기 때문이다.
상태 유지 구조에서는 클라이언트가 같은 서버에 계속 붙어 있어야 한다.
그런데 무상태 구조에서는 요청마다 필요한 정보가 다 있으므로, 아무 서버가 받아도 처리할 수 있다.
Figure 3.5 무상태 요청은 어느 서버가 받아도 처리할 수 있어 수평 확장에 유리합니다.
이 구조에서는 다음이 가능하다.
- 요청이 갑자기 늘어나면 서버를 여러 대 더 붙일 수 있다
- 특정 서버가 죽어도 다른 서버가 이어받을 수 있다
- 같은 요청을 어느 서버에 보내도 처리 방식이 같다
이것이 바로 스케일 아웃(scale-out), 즉 수평 확장에 유리하다는 뜻이다.
상태 유지의 한계와 무상태의 한계
| 항목 | 상태 유지 | 무상태 |
|---|---|---|
| 장점 | 요청 메시지가 짧아질 수 있음 | 서버 교체/확장/장애 대응이 쉬움 |
| 단점 | 같은 서버 의존, 확장 어려움 | 매 요청에 더 많은 정보가 필요할 수 있음 |
| 장애 시 영향 | 상태 가진 서버가 죽으면 문맥 손실 | 다른 서버가 이어받기 쉬움 |
그런데 모든 것을 무상태로 만들 수 있을까?
완전히는 어렵다. 예를 들어 로그인은 “이 사용자가 이미 인증되었다”는 상태를 어딘가에 유지해야 한다.
- 로그인 상태
- 장바구니
- 결제 진행 중인 사용자 식별
이런 경우에는 쿠키, 세션, 토큰 같은 장치가 필요하다.
하지만 핵심 원칙은 같다.
상태 유지는 꼭 필요한 부분에만 최소한으로 사용하고, 나머지는 최대한 무상태로 설계한다.
3. 비연결성: 요청이 끝나면 오래 붙잡지 않는다
HTTP를 설명할 때 자주 나오는 표현이 비연결성이다.
이 말을 실무 감각으로 바꾸면 이렇다.
요청과 응답이 끝났으면, 서버는 그 연결을 오래 붙잡지 않는 쪽이 자원 효율에 유리하다.
왜 이런 특징이 중요할까?
웹에서는 사용자가 계속 요청을 보내는 것 같아 보여도, 실제로는 대부분 이렇게 움직인다.
- 검색 버튼을 누른다
- 결과를 몇 초 또는 몇 분 본다
- 다음 행동을 한다
즉, 1시간 동안 사용자가 많아도 모든 사용자가 동시에 계속 연결을 붙잡고 있는 것은 아니다.
연결을 계속 유지하면 생기는 문제
Figure 3.6 비연결성은 놀고 있는 연결이 서버 자원을 오래 점유하지 않도록 돕습니다.
연결을 계속 유지하는 모델에서는, 실제로 요청하지 않는 클라이언트도 서버 자원을 붙잡고 있을 수 있다.
반면 요청-응답이 끝나면 정리하는 모델은 서버가 더 적은 자원으로 더 많은 사용자를 처리할 수 있다.
비연결성의 장점
- 서버 자원을 효율적으로 사용한다
- 동시에 많은 사용자가 있어도 idle 연결을 덜 유지한다
- 웹처럼 짧은 요청-응답이 많은 환경에 잘 맞는다
비연결성의 단점
하지만 매번 연결을 새로 만들면 비용이 있다.
- TCP 연결을 새로 맺어야 한다
- 3-way handshake 시간이 추가된다
- HTML, CSS, JS, 이미지처럼 리소스가 많으면 비효율이 커진다
즉, 비연결성은 자원 효율을 주지만 반복 연결 비용이라는 문제도 함께 가져온다.
4. 그래서 등장하는 최적화: 지속 연결
비연결성의 단점을 줄이기 위해 HTTP는 실제 구현에서 지속 연결(Persistent Connection) 을 적극 사용한다.
예전에는 keep-alive라는 표현으로도 많이 불렀다.
지속 연결이 없으면
HTML 하나, CSS 하나, JavaScript 하나를 받을 때마다 연결하고 끊는 흐름이 반복된다.
Figure 3.7 연결을 매번 새로 만들면 각 리소스마다 연결 비용이 반복됩니다.
지속 연결을 쓰면
연결을 한 번 맺고, 필요한 여러 요청과 응답을 같은 연결에서 처리한 뒤 마지막에 정리한다.
Figure 3.8 지속 연결은 짧은 구간에서 같은 연결을 재사용해 반복 비용을 줄입니다.
이렇게 하면 다음 이점이 생긴다.
- 반복 연결 비용 감소
- 페이지 로딩 속도 개선
- 여러 리소스를 받는 브라우저 환경에 적합
비연결성과 지속 연결은 모순일까?
겉으로는 모순처럼 보이지만, 실제로는 이렇게 이해하면 된다.
- 비연결성: 서버가 연결을 영원히 붙잡고 상태를 유지하지 않는 철학
- 지속 연결: 같은 페이지 로딩처럼 짧은 구간에서는 연결을 재사용해 성능을 높이는 최적화
즉, “항상 오래 연결 유지”가 아니라, 필요한 동안만 효율적으로 재사용하는 것이다.
HTTP/2, HTTP/3는 무엇을 더 하느냐?
이후 버전에서는 이 연결 재사용을 더 효율적으로 만든다.
- HTTP/2: 같은 연결에서 여러 요청을 더 잘 처리하도록 개선
- HTTP/3: 연결 설정과 지연 문제를 더 줄이도록 개선
이번 학습 단계에서는 “HTTP/1.1의 의미를 먼저 이해하고, 그 위에 성능 최적화가 추가된다” 정도로 잡으면 충분하다.
5. 실무에서 어떻게 기억하면 될까?
이 장의 개념은 단순 정의보다 설계 기준으로 기억하는 것이 중요하다.
- 클라이언트와 서버는 역할을 분리한다.
- 요청은 가능하면 자기완결적으로 만든다.
- 상태 유지는 꼭 필요한 경우에만 최소화한다.
- 서버는 idle 연결을 오래 붙잡지 않는 쪽이 유리하다.
- 하지만 실제 웹 성능을 위해 연결 재사용은 적극 활용한다.
Figure 3.9 좋은 HTTP 설계 감각은 역할 분리, 무상태, 연결 효율을 함께 보는 것입니다.
이번 장 정리
클라이언트-서버 구조: 클라이언트는 UI와 사용자 경험에 집중하고, 서버는 비즈니스 로직과 데이터 처리에 집중한다.
무상태(Stateless): 서버가 이전 요청 문맥을 기억하지 않는다. 요청이 자기완결적이어야 한다.
무상태의 장점: 서버 교체, 수평 확장, 장애 대응에 유리하다.
상태 유지의 예외: 로그인 같은 기능은 어쩔 수 없이 상태가 필요하므로 최소한으로만 유지한다.
비연결성: 요청-응답이 끝난 뒤 연결을 오래 붙잡지 않아 서버 자원을 효율적으로 쓴다.
지속 연결: 반복 연결 비용을 줄이기 위해 같은 연결을 잠시 재사용하는 최적화다.
확인 질문
- HTTP의 클라이언트-서버 구조가 단순한 모델 이상으로 중요한 이유는 무엇일까?
- 상태 유지와 무상태를 “점원 비유”로 설명하면 어떻게 다른가?
- 무상태 설계가 왜 스케일 아웃에 유리한가?
- 비연결성이 서버 자원 측면에서 유리한 이유는 무엇인가?
- 비연결성의 단점을 지속 연결이 어떻게 보완하는가?