새로운 내용을 공부할 때
새로운 내용의 공부를 시작할 때 용어의 정의를 이해하지 못하거나 정확하게 알지 못한다면 그 용어가 포함된 문장을 이해하지 못합니다.
작은 단어 하나가 내용을 이해하지 못하게 하기 때문에 용어를 정확하게 이해하는 것이 중요합니다.
TIL) HTTP과 느슨한 결합에 대한 고민
📌 2025-02-24 TIL
1. 오늘의 학습 주제
- HTTP이 없기 전에는 어떤 환경에서 데이터를 주고 받았을까
- HTTP는 어떤 문제를 해결하기 위해서 어떤 구조를 가지고 왔을까
- 이런 구조를 선택하면 같은 공통점을 갖게 되는 걸까
- 왜 팀 버너스리는 클라이언트-서버 구조를 선택한걸까
2. 학습 내용
HTTP 프로토콜의 탄생 배경과 무상태로 얻는 트레이드 오프를 생각해봤다.
이런 비슷한 구조를 가진 다른 소프트웨어도 같은 공통점과 트레이드 오프를 가지지 않을까 생각이 들었다.
HTTP이 왜 탄생했을까
HTTP 프로토콜이 생기기 전에는 어떤 네트워크 환경에서 데이터를 주고 받았는지 생각해볼 필요가 있었다.
HTTP 프로토콜 이전에는 하드웨어나 운영체제의 고유 프로토콜을 사용해서 네트워크 통신을 하려면 내부 로직을 알고 있어야 했다.
연구진들의 논문이나 자료를 공유하기 위해서 서버와 클라이언트 간 통신이 필요했다.
그때 TCP/IP 기반을 채택한 이유도 같은 이유였다. 호환성과 확장성이 뛰어나고 하드웨어나 운영체제에 독립적인 프로토콜이었기 때문에 TCP/IP를 기반으로 애플리케이션 계층 프로토콜을 개발했다.
클라이언트와 서버 간 통신에서 내부 로직을 알지 못해도 요청과 응답 방식만 규격화한다면 디바이스에 상관없이 통신이 가능해졌다.
구조는 강한 결합이 아닌 느슨한 결합으로 내부 로직을 몰라도 인터페이스만 정의된다면 서로 영향 없이 각자 개발이 가능했고 빠른 개발과 확장이 가능해졌다.
HTTP 프로토콜의 특이점은 무상태성(Statelessness)이다. 서버는 클라이언트의 상태를 저장하지 않기 때문에 요청마다 독립적으로 처리할 수 있다.
이 덕분에 서버 확장성에 유리하지만, 클라이언트가 상태를 유지해야 하므로 쿠키나 토큰 기반 인증 같은 상태 관리 기법이 필요하다.
HTTP 프로토콜의 철학은 확장성과 플랫폼 독립성이라고 생각한다.
어떤 운영체제나 디바이스라도 동일한 양식으로 요청을 한다면 서로 어떤 서버와 클라이언트인지 몰라도 통신할 수 있기 때문이다.
그런데 이런 생각도 들었다.
왜 클라이언트-서버 구조일까?
왜 클라이언트-서버일까? 서버-서버는 가능한 게 아닐까?
클라이언트-서버 모델은 당시 네트워크 환경뿐만 아니라 역할 분리와 확장성이라는 큰 장점 때문에 선택되었다.
- 클라이언트는 사용자와의 상호작용(UI) 및 요청 전송을 담당하고
- 서버는 비즈니스 로직과 데이터 저장을 처리하며 독립적으로 확장될 수 있다.
이를 통해 클라이언트와 서버가 독립적으로 개발되고 배포될 수 있었으며, 다양한 디바이스와 운영체제에서 동작할 수 있는 유연성을 얻었다.
물론 그때 당시 네트워크와 하드웨어 기술은 좋지 않았다.
서버-서버가 통신하려면 서로 IP를 알고 있어야 했고, 직접 IP를 전달하면 강한 결합으로 묶여서 확장하기 어려운 구조가 되었다.
그러면 DNS로 통신하면 되지 않을까?
하지만 당시 DNS 성능이 매우 안 좋았다.
DNS 서버 IP 주소 매핑을 변경하려면 초단위가 아니라 주단위가 걸렸다고 한다.
그러니 그럴 바에는 그냥 IP를 직접 사용해서 통신하는 게 나았다.
다시 강한 결합이 되고 확장하기 어려운 구조이기에 서버-서버 구조는 포기한 게 맞다고 생각한다.
느슨한 결합
데이터 요청과 응답을 표준화해서 내부 로직을 알지 못하더라도 양식만 지킨다면 통신이 가능하게 했다.
이런 구조는 객체지향 프로그래밍에서 인터페이스와 유사하다고 생각했다.
요청에 필요한 오브젝트와 메소드명, 인터페이스 이름만 알고 있으면 내부 로직이 어떻게 돌아가든 상관없이
반환타입(응답)에 대해서만 코드를 작성하면 된다.
이렇게 느슨한 결합일 경우 메서드를 사용하는 측과 메서드를 구현하는 측이 각자 개발할 수 있는 것과 같다.
HTTP도 느슨한 결합을 하여 확장성과 범용성을 챙길 수 있었다.
요청과 응답 규격
요청과 응답은 네이버페이 주문과 같다고 생각했다.
네이버페이에 구매자는
-
내가 주문한 물건(url)
-
내가 받을 주소 (ip)
-
택배를 수령할 위치(accept)
-
반품인지 주문인지 교환인지 (method)** 등이 필요하다.
네이버페이 판매자는
- 주문이 제대로 들어왔는지 (code)
- 물건이 유리인지, 김치인지 (content-type) 등이 필요하다.
데이터베이스와의 연관성
관계형 데이터베이스는 강한 결합 구조라고 생각하고 NoSQL은 느슨한 결합이라고 생각한다.
관계형 데이터베이스**는 비정규화나 정규화 여부에 상관없이 테이블 간의 관계를 맺어야 한다.
이때 트랜잭션 일관성(ACID)을 보장하여 데이터 정합성을 유지한다.
하지만 이러한 강한 결합과 트랜잭션 일관성으로 인해 수평 확장이 어려워지고 수직 확장에 의존하게 된다.
만약 수평으로 나눈다면 서버-서버끼리 통신하여 데이터 정합성을 맞춰야 하고
어디에 정보가 들어갔는지 규칙이 또 필요하게 된다.
그리고 서버끼리 통신하여 테이블을 조인하다 보니 성능 저하도 발생할 수밖에 없다.
반면에 NoSQL은 CAP 이론에 기반하여 일관성(Consistency), 가용성(Availability), 분할 내구성(Partition Tolerance) 중 일부를 트레이드오프했다.
대부분의 NoSQL은 가용성과 분할 내구성을 선택하면서 데이터 일관성은 부분적으로만 유지하거나 지연 일관성을 허용했다.
수평 확장에 적합하도록 설계되었고, 분산해서 데이터를 저장하기 때문에 데이터 일관성이 맞지 않을 수 있지만 그건 이미 고려한 예상 범위내라고 생각한다.
빠른 조회와 조인의 복잡성이 사라지고 유연한 방식을 얻었다.
데이터끼리 강한 결합이 아닌 느슨한 결합이라서 특정 데이터가 수정되어도 다른 데이터는 영향이 없기에 일정한 속도가 유지될 수 있다고 생각된다.
댓글남기기