HTTP의 간단한 복습이 목적이다.
HTTP
HyperText Transfer Protocol의 약자인 HTTP는 클라이언트 서버 구조에서 데이터를 주고받는 규약입니다.
과거에 HTTP는 html 문서와 text만을 전송하기 위한 목적이었다면 요즘에는 수많은 데이터를 HTTP를 통해 전송합니다.
이미지, 음성, 영상, 파일, JSON, XML 등등 거의 모든 형태의 데이터를 전송할 수 있습니다.
소수의 응용프로그램만 TCP/IP 연결을 통해 데이터를 주고 받습니다. (예를 들어 게임 서버와 데이터를 주고받을 때)
HTTP 역사
HTTP는 1991년 부터 명세가 조금씩 발전했습니다. 하지만 가장 많이 사용하는 HTTP/1.1 명세와 최근 점차 사용량이 늘어가고 있는 HTTP/2, HTTP/3도 존재합니다.
HTTP/1.1의 명세인 RFC2068(1997)에서부터 RFC7230~7235(2014)까지 많은 변화가 존재했으며 RFC7230으로 명세를 공부하는 것도 좋습니다.
HTTP 기반 프로토콜
HTTP 기반 프로토콜은 HTTP 버전에 따라 사용되는 프로토콜이 달라집니다.
TCP와 같은 연결지향성을 가진 HTTP는 HTTP/1.1 버전과 HTTP/2 버전이 있으며 HTTP/3은 UDP를 기반으로 구현되었습니다.
HTTP 특징
HTTP의 특징은 클라이언트 서버구조를 가진다는 점입니다. 요청과 응답으로 데이터를 교환하며,
무상태 프로토콜, 즉 비연결성을 가지고 있다는 점과 단순하고 활용 가능성이 많다는 점이 특징입니다.
- 클라이언트 서버 구조를 가진다는 것은 클라이언트가 서버에 요청을 보내면 클라이언트는 응답이 올 때까지 대기하며 응답이 오면 동작하는 구조입니다. 여기서 주목할 점은 클라이언트와 서버를 나누었다는 점을 들 수 있습니다. 클라이언트와 서버 구조가 나누어지면서 클라이언트와 서버는 독립적인 발전을 이룰 수 있었습니다.
클라이언트는 사용자의 편의성과 UI에 관해서만 집중을 진행할 수 있으며, 서버는 실제 사용자 요청 트래픽에 대한 처리 및 구조 설계 등... 많은 관심사가 분리되어 발전되었다고 할 수 있습ㄴ디ㅏ.
- stateless는 HTTP 프로토콜의 장점입니다. 왜 상태를 저장하지 않는데 장점이라고 할 수 있을 까요?
stateless의 반대의 의미를 가지는 statefull인 경우 다음과 같은 문제가 발생할 수 있습니다.
클라이언트의 정보를 하나의 서버가 관리를 해야 한다. 클라이언트의 요청이 늘어날 때마다 그 정보를 서버에 저장을 해야 한다라는 것은 해당 서버 다운이 일어나면 클라이언트의 모든 정보가 초기화된다는 문제를 가지고 있습니다.
분명 서버에 클라이언트의 정보를 저장함으로써 빠른 응답과 적은 요청 파라미터 등 장점이 존재하겠지만 이는 서버 장애에 유연하게 대응하지 못하는 서버 설계를 유발합니다.
이와 반대로 stateless는 클라이언트가 요청 시마다 모든 정보를 넘겨주어야 합니다.
예를 들어 요청 시마다 로그인했다는 정보와 내가 요청할 정보를 매 순간마다 넘겨야 한다는 것입니다. 그러면 서버가 해당 모든 정보를 통해 사용자가 요구한 일을 처리할 것입니다. 우리는 이러한 일을 session과 cookies를 가지고 처리하기도 합니다.
언뜻 보기에 stateless는 불편함을 주는 것으로 보이지만 다음과 같은 상황에 매우 유리합니다.
하나의 서버로 처리하는 것이 아닌 라우터 서버에서 혹은 프락시 서버에서 로드밸런싱을 한다고 가정했을 경우
다양한 서버에서 클라이언트 요청을 처리할 수 있습니다. 그 이유는 모든 정보가 요청에 담겨 있기 때문에 요청을 받는 서버가 기존 서버가 아니더라고 해당 요청을 처리할 수 있음을 뜻합니다. 그렇기 때문에 정확한 특정 시간에 대용량 트래픽이 발생한다고 예상이 되는 경우 백엔드 개발자는 scaleout을 통해 무한히 서버 증설로 해당 트래픽을 받아낼 수 있습니다. 또는 초기 요청된 서버의 예기치 못한 서버 다운이 일어나도 클라이언트는 장애가 발생한 사실도 모르고 자연스레 요청이 처리됩니다. 따라서 유연한 확장성, 서버의 가용성을 확보할 수 있다는 점이 특징입니다.
- 비연결성
HTTP는 기본적으로 클라이언트와 연결을 유지하지 않습니다. 그 이유는 실제 웹 애플리케이션을 제공하여 로그를 보면 동시에 처리하는 요청은 매우 적고 드문드문 요청이 들어오기 때문입니다. 만약 연결성을 가진다면 요청했던 모든 클라이언트와 연결을 유지하고, 연결된 클라이언트가 아무런 요청을 보내지 않는다 해도 서버는 해당 클라이언트와 요청을 유지함으로써 서버의 자원이 소모될 수 있습니다.
HTTP 한계
이 한계를 극복하기 위해서 HTTP의 여러 버전이 나오긴 합니다. 그렇기 때문에 가장 많이 사용하는 HTTP/ 1.1 기준으로 설명드리겠습니다.
HTTP/1.1은 TCP/IP 기반으로 동작하는 상위 프로토콜입니다. 그렇기 때문에 요청마다 3-way-handshake를 배제할 수가 없습니다. 또한 비연결성이라는 특징 때문에 매 요청마다 서버 자원을 요청할 시 3-way-handshake가 매번 발생하게 됩니다.
예를 들어 html문서 하나를 요청해서 그 안에는 자바스크립트, CSS, 이미지, 동영상 등 수많은 부가 자원이 존재합니다. 요청마다 부가 자원들을 다운로드하기 위해 반복적으로 요청하는 것은 정말 많은 시간을 소요합니다.
지금은 HTTP 지속 연결 (Persistent Conections)로 문제를 해결할 수 있습니다. Keep Alive 기능이라고 하면 이해가 쉬울 것입니다.
HTTP/2./3에서는 이러한 한계를 더욱더 최적화한 버전입니다.
발생할 수 있는 문제
실제 애플리케이션 개발 시 고려해야 하는 점이 존재합니다. 특정 시점에 대용량 트래픽이 몰릴 수 있는 요청 같은 경우 stateless적으로 처리하는 것이 사실상 서버의 가용성 측면으로 매우 좋은 설계지만 그렇지 못한 경우가 발생할 수 있습니다.
1. 이벤트를 진행하는데 로그인한 사용자만 해당 페이지에서 이벤트를 할 수 있는 경우
- 이 경우 사용자가 로그인한 사실을 서버에 저장을 해야만 합니다. 뭐 JWT나 세션 서버끼리의 동기화를 통해 처리할 수도 있지만 그렇게 할 수 없는 상황이라는 점을 가정하면 어떻게 해야 할까요?
기술적으로 처리하는 것이 아닌 사용자 경험 기반으로 트래픽을 늦출 수 있는 방법이 가장 최선의 방법일 수 있습니다.
이벤트를 참여하기 위한 여러 단계를 두고 , 볼거리, 추가적인 정보를 stateless적으로 제공하고, 실제 이벤트 참여 요청 초당 트래픽을 분산시키는 방법도 또 하나의 방법이 될 수 있습니다....
'느리게 변하는 지식 > Network' 카테고리의 다른 글
커넥터와 트랜시버 (0) | 2023.01.10 |
---|---|
HTTP Redirection (0) | 2021.12.06 |
Proxy 개념(1) (0) | 2021.10.31 |
방화벽, DMZ, 내부망 (0) | 2021.10.28 |
DHCP (0) | 2021.07.10 |
댓글