🤔 질문 :
💡인터넷에서 컴퓨터 둘은 어떻게 통신하나?
단순하게 생각하자면
요청을 보낸다 → 대답을 듣는다
이렇게 생각할 수 있다.
🔥 하지만 인터넷 네트워크는 우리가 생각하는 것보다 굉장히 복잡하다.
단순하게 네트워크 상에 단 2대의 컴퓨터가 1 대 1로 통신한다면 요청을 주고 받기 위한 경로가 단순할 수는 있다. 하지만 이 세계의 네트워크 안에는 수 많은 컴퓨터가 존재하고, 그 네트워크 또한 많은 네트워크가 존재한다.
그렇기에 데이터를 정확한 목적지에 손실 없이 보내는 것이 중요하고, 이 전송은 복잡할 수 밖에 없다.
그렇다면 네트워크 기기의 데이터를 어디에서 어디로 보낼지 어떻게 타겟팅을 할까?
💡그래서 우리는 IP라는 것을 사용하기로 했다.
IP : Internet Protocol (인터넷 프로토콜)의 약자 인터넷이 존재하는 네트워크 안에서 정보를 송/수신 하는 통신에 대한 규약을 의미.
간단하게 주소라고 생각해볼 수 있다.
마치 우리집의 주소가 경기도 OO시 OO구 OO동 OO아파트 123동 567호 인 것처럼!
그렇다면, 데이터를 당근하기 위해 구매자의 주소로 보내는 내 물건이라고 생각해보자!
위의 그림처럼 택배 상자에 보낸 주소와 받는 주소를 붙여 보내는 것처럼 패킷이라는 상자에 내용물을 담아 전송한다.
😒 문제 :
💡초창기 IP 프로토콜의 한계
- 비연결성
- 패킷을 받을 대상이 없어도 or 서비스 불능 상태여도 일단 전송한다.
- 내 당근을 받을 사람이 없거나, 당근 받는 사람이 연락이 두절이 되어도 일단 택배를 보내고 보는 것이다.
- 비신뢰성
- 중간에 패킷(택배 상자)이 사라져도
- 패킷이 순서대로 안와도
- 구분의 한계
- 같은 IP를 사용하는 서버에서 통신하는 Application이 둘 이상이여도 (당근을 받는 사람이 다른데도 일단 주소가 같으니 일단 보내면 한 명은 받겠지..)
🫢 해결 :
💡그래서 이렇게 하기로 했다 (+예시)
Internet Protocol Stack 4계층은 각각 Application, Transmission, Internet, Network Interface 으로 나뉘어져 있다. 각 계층에서는 정확하고 안전한 정보 전달을 위해 맡은 역할을 수행한다.
그리고 HTTP는 Application 계층에서 발전을 이루며 문제들을 해결하기 위해 계속 발전해왔다.
각 계층에서 이루어지는 매커니즘 또한 설명할 것이 많으나, 오늘은 HTTP에 대해서 중점적으로 다루어보자 한다.
🤔 HTTP란 무엇인가?
HTTP : “HyperText Transfer Protocol”의 약자 웹에서 정보를 교환하기 위해 사용되는 프로토콜
Web의 핵심 요소 중 하나이며, 이를 통해 웹 브라우저와 웹 서버간의 통신을 가능하게 해준다.
💡HTTP의 특성:
- 비연결성:
HTTP는 비연결성을 가진 프로토콜이다.
이는 클라이언트와 서버 간의 연결이 요청을 처리한 직후 바로 종료된다는 것을 의미한다. 이러한 특성은 많은 사용자와의 통신을 가능하게 해주지만, 연결을 매번 새로 설정해야하기 때문에 Over-Head가 발생할 수 있습니다 (택배 기사가 택배를 계속 왔다갔다 배송하게 되는 것과 비슷). 이를 해결하기 위해 HTTP/1.1에서는 지속적인 연결(Persistent Connection)이 도입되었습니다(택배 기사님 팔이 엄청 길어져서 양쪽 집의 문고리를 계속 잡고 바로바로 택배를 배송해주는 것과 비슷). - Stateless :
HTTP는 기본적으로 상태를 저장하지 않는 프로토콜이다.
즉, 이전 요청과 다음 요청 사이에 서로 관련성이 없다. 이 부분에 대해서는 아래의 구체적인 예시에서 설명을 이어하도록 하겠습니다. - 요청/응답 모델:
HTTP는 요청/응답 모델을 사용한다.
클라이언트(주로 웹 브라우저)는 요청을 보내고, 서버는 이에 대한 응답을 반환한다
클라이언트 : 당근주세요~ / 서버: 네 당근 보내드릴게요~ - Method:
HTTP는 다양한 메서드를 제공한다. 대표적으로는 GET, POST, PUT, DELETE 등이 있다.
각 메서드는 서버에 대한 다른 종류의 요청을 나타낸다. 각 메서드를 이용하여 서버에 존재하는 데이터를 요구, 변경, 저장, 삭제 등을 할 수 있다.
아래는 HTTP 메서드에 대한 설명이다.
GET 서버에서 정보를 검색하기 위한 요청.데이터를 변경하거나 영향을 주는 작업에는 사용되어서는 안 됩니다. POST 서버에 데이터를 제출하기 위한 요청.주로 리소스 생성 및 데이터 제출에 사용됩니다. PUT 특정 리소스를 갱신하거나 새로 생성하기 위한 요청. 전체 리소스를 대체하는 특성이 있습니다. PATCH 리소스의 일부분만을 수정하기 위한 요청. DELETE 특정 리소스를 삭제하기 위한 요청. HEAD GET과 유사하지만, 리소스의 본문(body) 없이 헤더 정보만을 요청. OPTIONS 대상 리소스가 지원하는 메서드의 종류를 알아보기 위한 요청. CONNECT 네트워크 터널을 설정하기 위한 요청. TRACE 요청을 테스트하거나 진단하기 위한 메서드.서버는 요청을 처리하지 않고, 받은 내용을 그대로 응답으로 돌려줍니다. - 상태 코드 (Status Code):
HTTP 응답에는 상태 코드가 포함되어 있다. 이는 요청의 성공, 실패, 그리고 다양한 상황을 나타다.
예를 들면, "200 OK"는 성공적인 요청을 나타내고, "404 Not Found"는 요청한 리소스를 찾을 수 없음을 나타낸다. - 버전:
HTTP는 시간이 지나면서 여러 버전으로 발전해왔다. HTTP/1.0, HTTP/1.1 그리고 HTTP/2는 대표적인 버전이다. 각 버전은 통신 방법, 연결성, 보안 등의 부분에서 차이점을 가지고 있다. 현재 HTTP/3가 개발되어 도입이 이루어지고 있다. - 보안:
기본 HTTP는 암호화되지 않은 텍스트 형태로 데이터를 전송한다. 이로 인해 중간자 공격(man-in-the-middle attack)에 취약하다는 문제가 있다 (중간에 배달 기사가 배달 음식을 빼먹는 행위와 비슷한 것). 이를 보완하기 위해 HTTPS가 도입되었는데, 이는 SSL/TLS 프로토콜을 사용하여 통신 내용을 암호화한다. 앞서 말한 HTTP/2 버전은 HTTPS 기반으로 구동된다.
이와 같이 HTTP는 웹의 핵심 프로토콜로, 웹 브라우저와 서버 간의 통신을 담당하며 다양한 기능과 특성을 가지고 있다.
❗Stateless 추가 설명
비유를 들어 설명해보자!
상점에서 쇼핑을 하는 과정을 생각해보세요.
- Stateful 상황:
- 당신이 상점에 들어가서 노트북을 구매합니다.
- 잠시 후, 다시 같은 상점에 들어가 방금 산 물건을 2개 구매하려고 합니다.
- 판매원이 당신을 기억하고 있어, “아까 노트북을 구매하셨죠? 2개 더 사셔서 할인 해드리겠습니다."라고 말합니다.
- 이 상황에서 판매원(Server)은 당신(Client)의 이전 행동(State)을 기억하고 있습니다.
- Stateless 상황:
- 당신이 상점에 들어가서 노트북을 구매합니다.
- 잠시 후, 다시 같은 상점에 들어가 같은 상품을 2개 구매하려고 합니다.
- 그러나 이번에는 다른 판매원이 당신을 서비스합니다. 이 판매원은 당신이 노트북을 구매한 사실을 전혀 모릅니다.
- 당신은 판매원에게 노트북을 구매했다고 말하지 않는 한, 그 판매원은 당신의 이전 구매 내역을 알 수 없습니다.
- 이 상황에서 판매원(Server)은 당신(Client)의 이전 행동(State)을 전혀 기억하고 있지 않습니다.
🤔 질문 : 그렇다면 기억하고 있는게 더 좋은 것 아닌가?
라는 생각이 들 수 도 있지만 다음 예시를 통해 설명해보겠다.
클라이언트가 노트북, 2개를 구매하겠다는 패킷을 전송하였다. 서버는 패킷에 대한 응답을 전송한다.
😒문제 : 중간에 서버 장애 발생한다면?
- 만약 중간에 서버가 다운이 되어 패킷을 전송하지 못했다면? 서버1에서는 어차피 패킷을 받았다해도 기억을 하지 못하기에 상관없이 서버 2가 하던 일을 받아서 할 수 있다.상태가 유지(Stateful) 이었다면, 요청 패킷 내용을 서버2와 3은 내용을 모르기에 패킷을 잡고 있던 서버 1만 일을 끝마칠 수 있다. 서버가 다운된다면, 요청을 다시 받기 전까지 응답을 줄 수 없는 상황이 발생하는 것이다.따라서 Stateless는 대용량 트래픽이 발생하는 서비스(ex. 추석 기차표 예매, 수강신청 등)에서 같은 기능을 하는 서버를 확장하여 사용하기 유리한 특성을 가지고 있다고 할 수 있다.
- 서버가 하나만 다운이 되어도 패킷의 손실이 엄청나게 발생한다!
- 클라이언트가 A 하나 뿐만 아니라 엄청나게 많다면?
- 🫢 대답 : 무상태 일 때는 Scale Out, 수평 확장에 유리하다!
- 모두가 어차피 상태를 보관하지 않으니 누가 해도 똑같이 모르는 상태로 일을 처리하기 때문이다.
💡HTTP 메세지는 어떻게 생겼는가?
🔥 HTTP 메시지에 모든 것을 넣어 전송
- HTML, TEXT
- IMAGE, 음성, 영상, 파일
- JSON, XML
- 거의 모든 형태의 데이터 전송 가능
- 서버간에 데이터를 주고 받을 때도 대부분 HTTP 사용
HTTP 메시지는 크게
요청 메시지(Request Message)
응답 메시지(Response Message)
로 나뉜다.
각 메시지는 시작줄, 헤더(Header), 그리고 선택적인 본문(Body)으로 구성됩니다.
HTTP 요청 메시지
1. 시작줄 (Start Line)
요청 메시지의 시작줄은 메서드, 요청 대상 URI, 그리고 HTTP 버전으로 구성된다. 예시: GET /index.html HTTP/1.1
2. 헤더 (Headers)
요청에 대한 메타데이터를 포함하며, 키: 값 형식으로 구성된다. 예시:
Host: [www.example.com](<http://www.example.com/>)
User-Agent: Mozilla/5.0
3. 본문 (Body)
데이터를 전송할 때 사용되는 부분이다. GET 요청과 같이 데이터를 전송하지 않는 요청에서는 생략될 수 있다.
HTTP 응답 메시지
1. 시작줄 (Start Line)
응답 메시지의 시작줄은 HTTP 버전, 상태 코드, 그리고 상태 메시지로 구성된다.
예시: HTTP/1.1 200 OK
2. 헤더 (Headers)
응답에 대한 메타데이터를 포함하며, 키: 값 형식으로 구성된다.
예시:
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
3. 본문 (Body)
서버에서 클라이언트로 전송된 데이터가 포함된다. HTML, 이미지, JSON 등 다양한 형태의 데이터가 본문에 포함될 수 있다.
- Body 예시 )
- HTML: 웹 페이지의 내용을 나타내는 경우 주로 사용됩니다.
htmlCopy code <!DOCTYPE html> <html> <head> <title>My Page</title> </head> <body> <h1>Welcome to My Page</h1> <p>This is a sample web page.</p> </body> </html>
- JSON: API 응답이나 클라이언트의 요청에서 주로 사용되는 데이터 형식입니다.
jsonCopy code { "name": "John Doe", "age": 30, "email": "johndoe@example.com", "address": { "street": "123 Main St", "city": "Anytown", "zipcode": "12345" } }
- XML: 이전에는 API 응답이나 데이터 교환 형식으로 많이 사용되었으나, 현재는 JSON에 의해 주로 대체되고 있습니다.
xmlCopy code <person> <name>John Doe</name> <age>30</age> <email>johndoe@example.com</email> <address> <street>123 Main St</street> <city>Anytown</city> <zipcode>12345</zipcode> </address> </person>
- Plain Text: 단순 텍스트 형식의 데이터를 전송할 때 사용됩니다.
kotlinCopy code Hello, this is a sample text message.
- Form Data: 웹 페이지에서 폼을 통해 데이터를 전송할 때 주로 사용되는 형식입니다.
makefileCopy code username=johndoe&password=secret&email=johndoe%40example.com
Reference :
[HTTP Docs](https://httpwg.org/specs/)