[웹을 지탱하는 기술] chp 6. HTTP의 기본

sameul__choi·2022년 3월 23일
0
post-thumbnail

HTTP는 TCP/IP를 베이스로한 프로토콜이다. TCP/IP의 기초 지식과 HTTP의 간단한 역사를 알아보고 HTTP의 메세지 구조와 프로토콜로서의 HTTP를 특징짓는 스테이트리스성에 대해서도 알아본다.

00 HTTP의 중요성

HTTP란 하이퍼텍스트 전송용 프로토콜이지만 실제로는 HTML, XML 같은 하이퍼텍스트 뿐 아니라 이미지, 음성, 동영상 JavaScript 프로그램 PDF 와 각종 오피스 도큐먼트 파일 등 컴퓨터에서 다룰 수 있는 데이터라면 모두 전송할 수 있다. REST의 중요한 특징인 Unifform 인터페이스, 스테이트리스, 서버, 캐시 등을 구현하고 있는 Web의 기반이 되는 프로토콜이다.

01 TCP/IP란?

HTTP는 TCP/IP를 기반으로 하고 있는데, 이는 인터넷의 토대로 구성하는 중요한 네트워크 프로토콜이다.

계층형 프로토콜

인터넷의 네트워크는 계층 구조를 가지고 있고, 각 계층별로 추상화하여 구현하면 하위 계층의 구체적인 사항에 좌우되지 않고 상위 계층을 구현할 수 있다.

네트워크 인터페이스 계층

물리적 케이블, 네트워크 어댑터에 해당하는 부분이다.

인터넷 계층

네트워크에서 데이터를 실제로 주고 받는 것을 담당하며 TCP/IP에서 IP가 여기에 해당한다. IP의 기본 통신 단위는 패킷이며 지정한 IP 어드레스와 패킷 단위로 데이터를 주고받으며 통신한다.

트랜스포트 계층

데이터의 무결성을 보증하는 것이 트랜스포트 계층의 역할이다. TCP/IP의 TCP가 여기 해당된다. TCP는 목적지의 상대에 대해 커넥션을 연결한다. 이 커넥션을 사용하여 데이터의 누락을 체크하고 데이터의 도달을 보증하게 된다. TCP로 접속된 커넥션에서 전송하는 데이터가 어느 애플리케이션으로 전달될지 결정하는 것이 포트번호 이다. 1~65535까지의 수치를 사용하며 HTTP는 디폴트로 80번 포트를 사용한다.

애플리케이션 계층

메일이나 DNS, HTTP를 실현하는 계층이다. TCP로 프로그램을 만들 때는 소켓이라는 라이브러리를 사용하는 것이 일반적이다. 소켓은 네트워크에서의 데이터 교환을 추상화한 API로, 접속, 송신, 수신, 절단 등의 기본적인 기능을 갖추고 있다. HTTP 서버와 브라우저는 소켓을 이용하여 구현한다.

HTTP를 독자적으로 구현한 라이브러리가 이미 준비되어 있기 때문에 소켓을 사용해 HTTP를 독자적으로 구현할 일은 없다. 하지만, 웹 서비스와 웹 API를 개발함에 있어서는 프레임워크의 세세한 동작과 설정, 파라미터 등이 프로토콜 수준에서 어떻게 동작하는 지 파악해 둘 필요가 있다.

02 HTTP의 버전

HTTP 0.9 - HTTP의 탄생

버너스리가 1990년에 웹을 발명했을 때 사용하던 프로토콜을 HTTP 0.9라고 부른다. 이 최초의 HTTP는 아주 단순했다.

HTTP 0.9에는 현재의 HTTTP와는 다르게 헤더가 없다. 메서드 또한 GET 뿐이었다.

HTTP 1.0 - HTTP 최초의 표준화

HTTP 1.0은 IETF에서 표준화가 이루어진 최초의 버전이다. 헤더의 도입, GET 이외의 메서드 추가 등 HTTP1.1로 이어지는 기본적인 요소들이 도입이 되었다. 기존에 구현된 것을 기반으로 한 스펙이었으므로 상호운용성이 확보되어 있다고 말하기 어려운 상황이었지만, HTTP 1.1로 가는 확실한 발판이 되었던 스펙이었다.

HTTP 1.1 - HTTP의 완성

HTTP 1.0의 기능에 더해 채널 전송, Aceept 헤더에 의한 콘텐트 네고시에이션, 복잡한 캐시 컨트롤, 지속적 연결 등의 기능이 추가 되었다.

지금은 HTTP 1.1이 책정되고 나서 이미 20년 이상 지났기 때문에 대부분의 HTTP 클라이언트 라이브러리와 웹 서버는 HTTP1.1을 지원하고 있다.

03 클라이언트와 서버

자, HTTP의 구체적인 구조를 살펴보자 웹은 아키텍처 스타일로 클라이언트/서버를 채용하고 있다. 즉, 클라이언트가 정보를 제공하는 서버에 접속하여 각종 요청을 보내고 응답을 받는 구조이다.

04 요청과 응답

위와 같이 HTTP에서는 클라이언트가 내보낸 요청ㅇ르 서버에서 처리하고 응답을 돌려준다. 이런 프로토콜을 가리켜 요청/응답형 프로토콜이라고 한다.

서버에서의 처리에 시간이 많이 걸리는 경우라도 요청을 보낸 클라이언트는 응답이 돌아올 때까지 대기한다. 이것은 HTTP가 동기형 프로토콜이기 때문이다. 이런 메세지들이 오고갈 때 클라이언트와 서버에서 이루어지는 일들은 다음과 같다.

클라이언트에서 일어나는 일들

클라이언트에서는 요청을 송신하고 응답받을 때 다음의일들을 수행한다.

  1. 요청 메세지 구축
  2. 요청 메세지 송신
  3. 응답이 돌아올 때 까지 대기
  4. 응답 메세지 수신
  5. 응답 메세지 해석
  6. 클라이언트의 목적을 달성하기 위해 필요한 처리

서버에서 돌아온 응답을 해석한 결과 재요청이 필요한 경우도 있다. 예를 들어, mentorbook.com에서는 이미지와 스타일 시트로의 링크를 여러개 포함하고 있기 때문에 HTML을 렌더링 하기 위해 50회 이상 요청을 보내야만 한다.

마지막으로 클라이언트는 자신의 목적을 달성하기 위한 처리를 수행한다. 브라우저라면 HTML을 렌더링 해 윈도우에 표시하는 처리를 하고, 검색엔진용으로 데이터를 수집하는 로봇이라면 HTML의 해석결과를 데이터 베이스에 저장하는 처리를 한다.

서버에서 일어나는 일들

  1. 요청을 대기
  2. 요청 메세지 수신
  3. 요청 메세지 해석
  4. 적절한 애플리케이션 프로그램으로 처리를 위임
  5. 애플리케이션 프로그램을로 결과를 취득
  6. 응답 메세지 구축
  7. 응답 메세지 송신

우선 요청 메세지를 해석해서 클라이언트의 요청을 알게된다. 다음은 HTML을 렌더링 할 애플리케이션에게 처리를 위임하고 결과 HTML을 취득한다. 이때 애플리케이션은 데이터 베이스로부터 최신 기사를 가져오거나 링크를 생성한다. 애플리케이션으로부터 HTML을ㄹ 가져오면 적절한 헤더를 부가해 응답 메세지를 구축하고 클라이언트에 송신한다.

05 HTTP 메세지

요청 메세지와 응답 메세지를 합해 HTTP 메세지라고 부른다. HTTP 메세지가 어떤 구조를 갖고 있는지 알아보자.

요청 라인

요청 라인은 메서드와 요청 프로토콜 버전으로 구성된다.

GET /search?q=test&debug=true#n10 HTTP/1.1
Host:example.com:8080

요청 라인에는 경로 이후의 문자열이 들어갑니다. 포트 번호는 Host 헫더에서 지정합니다. 요청 URI는 지금까지 살펴본 예와 같이, 경로 이후의 문자열이 되거나 혹은 절대 URI가 된다.

경로를 사용한 경우에는 Host 헤더가 필수적이지만, 절대 URI를 사용한 경우에는 Host 헤더를 생략할 수 있다.

헤더

요청 메세지의 둘째 줄 부터는 헤더가 이어진다. 헤더는 메세지의 메타 데이터이다. 하나의 메세지는 복수의 헤더를 가질 수 있다. 각 헤더는 '이름:값'의 구성을 하고 있다. 앞의 예에서는 'HOST'라는 이름에 'example.com'라는 값이 연결되어 있다.

바디

앞의 예에서는 등장하지 않았지만, 헤더 뒤에 바디가 이어지는 경우도 있다. 바디에는 그 메세지를 나타내는 본질적인 정보가 들어간따. 예를 들어, 리소스를 새로 작성하거나 갱신할 때는 요청의 바디 부분에 리소스의 표현 자체가 들어간다.

응답 메세지

다음으로 응답 메세지를 살펴보자. 앞에 나왔던 URI로 요청이 성공하면 서버는 다음과 같은 응답을 클라이언트에게 보낸다.

스테이터스 라인

응답 메세지의 첫 줄은 스테이터스 라인이라고 하며, 프로토콜 버전, 스테이터스 코드, 텍스트 구문으로 구성된다. 스테이터스 코드는 요청의 결과를 프로그램으로 처리 가능한 수치 코드로 표현한다. 이 경우의 200은 요청이 성공했다는 것을 나타낸다.

헤더

Content-Type 헤더에서 HTML의 MIME 미디어 타입과 그 문자 인코딩 방식을 지정하고 있다.

바디

이 응답 메세지에는 바디도 포함되어 있다. 헤어돠 바디는 빈 줄로 구분된다. 이 예에서는 바디에 HTML이 포함되어 있다.

HTTP 메세지의 구성요소

HTTP 메세지의 구조를 정리하면 다음과 같다.

첫째 줄은 스타트 라인이라고 총치하고 요청 메세지의 경우는 요청 라인, 응답 메세지의 경우는 스테이터스 라인이 된다.

스타트 라인에 이어 헤더가 나열되고 헤더 각 행의 줄바꿈은 CRLF이다. 헤더의 종료는 빈 줄로 식볋한다. 헤더는 생략할 수 있다. 헤어데 이어서 바디를 가질 수 있다. 바디에는 텍스트뿐 아니라, 바이너리 데이터도 들어갈 수 있다. 바디도 생략이 가능하다.

06 HTTP의 스테이트리스 성

HTTP는 스테이트리스한 프로토콜로 설계되어 있다. 클라이언트의 어플리케이션 상태를 보존하지 않는다는 제약이다.

스테이트풀의 결점

서버가 클라이언트와 애플리케이션 상태를 기억하는 것은 클라이언트의 수가 증가ㅏ함에 따라 어려워지게 된다.

하나의 서버가 수용할 수 있는 클라이언트의 수에는 한계가 있고, 복수의 서버간 애플리케이션 상태를 동기화 하고 어떤 서버라도 동일한 애플리케이션 상태를 사용할 수 있도록 해야만한다. 이는 오버헤드가 생기게 되므로 좋은 방법이 아니다. 스케일업이 힘들어 지기 때문이다.

스테이트리스의 이점

이런 문제점을 해결하는 것이 스테이트리스 아키텍처이다. 스테이트리스는 클라이언트가 요청 메세지에 필요한 정보를 모두 포함시킨다. 이처럼 요청을 처리하는데 필요한 정보가 모두 포함되어 있는 메세지를 가르켜 '자기 기술적 메세지'라고 한다. 스테이트리스한 아키텍쳐에서는 서버가 클라이언트의 애플리케이션 상태를 기억하는 대신에 클라이언트가 자신의 애플리케이션 상태를 기억하고 모든 요청을 자기 기술적 메세지로 송신한다. 때문에 서버 시스템이 단순해지고, 서버는 새로 오는 요청에 집중할 수 있게 된다.

이 특성을 이용하ㅏ면, 스테이트리스한 시스템으르 확장시켜가는 것이 간단해 진다. 클라이언트가 늘어나면 단순히 서버를 증설하면 된다. 처리에 필요한 정보가 모두 요청에 포함되어 있기 때문에 클라이언트는 어느 서버로 요청을 보내도 상관이 없다.

스테이트리스의 결점

  1. 퍼포먼스의 저하
    서버를 스테이트리스로 만들기 위해서는 클라이언트는 매번 필요한 정보를 모두 송신하지 않으면 안된다. 이것은 다음의 이유에서 퍼포먼스에 영향을 미친다.
  • 송신할 데이터의 양이 많아진다.
  • 인증 등 서버에 부하가 걸리는 처리를 반복한다.

모든 정보를 재전송해야하면서 양에 따라 네트워크 대역을 낭비할 수 있다. 또한, 인증처리 등으로 서버에 부하가 걸리는 문제도 있다. 인증처리의 구현 방법에 따라 다르겠지만, 데이터베이스에 사용자 정보과 패스워드가 들어 있을 경우 인증을 할 때마다 디비 엑세스가 필요하게 된다. 디비 엑섹스는 무거운 처리이기 때문에 이것을 반복하면 퍼포먼스가 떨어지게 된다.

  1. 통신 에러에 대한 대처
    또한, 스테이트리스 방식에서는 통신 에러 발생 시의 대처도 문제가 됩니다. 우선은 스테이트풀의 예를 살펴보자. 클라이언트의 응답이 오지 않을 때 다시 한 번 요청을 반복할 수 있다. 서버가 클라이언트의 상태를 기억하고 있기 때문이다. 하지만 스테이트리스의 경우는 이렇게 되지 않는다.

스테이트리스한 아키텍처에서는 네트워크 트러블이 발생했을 때 그 요청이 처리 되었는지 알 수가 없다.

07 심플한 프로토콜의 강점

HTTP의 가장 큰 특징은 그 심플함이다. HTTP 1.1이 되면서 HTTP 0.9만큼의 심플함은 사라졌지만, 그래도 프로토콜을 심플하게 유지하려는 노력이 계속 되었다. HTTP 가 심플하기 때문에 비로소 브라우저는 PC뿐 아니라 그 밖의 다양한 디바이스에서도 구현 될 수 있게 되었다. 또한, 그 심플함 덕분에 웹 서비스와 웹 API가 같은 프로토콜로 실현될 수 있는 것이다.

0개의 댓글