전공자인데 아직 서버가 뭔지 정확히 모르겠다고 하면 웃길 수 있으나 서버라는 이름만 자주 나오고 부분적으로만 등장할 뿐 교육과정에서 정확히 그게 뭔지 제대로 다뤄지지 않는다. 그래서 이참에 확실하게 이해해보려 한다.
서버란?
서버의 "실체"를 이해하기 위해서는 하드웨어와 소프트웨어의 2가지 측면을 모두 고려해야 함.
서버는 기본적으로 클라이언트에게 서비스를 제공 - 요청을 처리하고, 데이터를 관리 - 하는 시스템.
1 물리적 서버 Physical Server:
서버는 직육면체 형태의 컴퓨터다. 그걸 모아서 위와 같이 다양한 형태로 쌓아둔다.
데스크톱 본체와 유사하게 CPU, RAM, 디스크, NIC 등으로 이루어져 있지만, 일상 작업을 처리하는 용도인 데스크톱과는 다른 기능을 키운 컴퓨터다. 서버는 앞서 말했든 네트워크를 통해 다수의 클라이언트에게 서비스를 제공하는 것을 목적으로 한다. 사용되는 CPU, RAM의 성능도 훨씬 좋고, 확장성, 신뢰성, 내구성 등의 특징들이 훨씬 뛰어나다. 다만 일반인을 대상으로 만들어진 게 아니기 때문에 사용자 편의성에서는 떨어진다.
이 서버를 더 효율적으로 활용해보기 위해서 등장한 게 가상 서버다. 하이퍼바이저와 VM 등을 일컫는다. 예를 들어 1개의 서버가 1개의 프로그램에 의해 매일 쥐똥만큼씩만 사용된다고 한다면 안 쓰이고 남는 용량이 아까우니, 애초에 1개의 물리 서버지만 여러 개의 프로그램을 돌릴 수 있도록 각각의 프로그램에 서버의 일부를 할당하여, 마치 여러 개의 서버가 있는 것처럼 하는 것이 가상화다. 이 또한 물리서버의 개념에 포함된다.
결론적으로 소프트웨어적 "서버"를 구현하는 데 있어서, 숙주가 필요한데 숙주로 사용 가능한 것들 중에 이 물리적 "서버"가 있는 것이다. 그러나 꼭 이거여야만 하는 것은 아니다. 클라우드도, 데스크톱도 서버의 숙주로 사용 가능하다. 그러니 더 이상 이 서버랑 소프트웨어적 서버를 헷갈리지 말자.
2 소프트웨어적 서버:
서버 운영체제 위에서 실행되며, 클라이언트에게 특정 서비스를 제공하는 소프트웨어. 말 그대로 식당에서처럼, 클라이언트에게 서비스를 제공하는 주체라고 생각하면 편하다.
- 웹 서버: HTTP 요청 처리하고, 웹 페이지를 제공. 백엔드 엔지니어가 다룰 그것. ex) Apache, Nginx 등
- 웹 앱 서버: 비즈니스 로직을 처리하고, 클라이언트 요청에 응답하는 소프트웨어. ex) tomcat 등
- DB 서버: DB를 호스팅하고, 쿼리를 처리하는 소프트웨어. ex) MySQL, PostgreSQL 등
그러니까 앞으로 백엔드 개발자가 서버를 구축한다고 할 때의 그 서버는, 소프트웨어적 서버인 것이다. 이제 특별히 명시되지 않는 한, 물리서버에 대한 관심은 끄자. 클라이언트 - 서버 할 때의 그 서버, 그 추상적인 개념이 메인이다.
웹 서버와 웹 앱 서버의 정확한 구분 <- 멍청하게 부르는 습관들 때문에 헷갈리는 게 당연한 것임.
그러니까 서버는 클라이언트의 요청을 처리하는 녀석인데, 서버의 종류에는 여러가지가 있다. 그중 웹에서 상호작용하는 녀석은 "웹 서버"다. 여기까지는 자명한데, 여기서 헷갈리는 부분이 등장한다.
클라이언트가 "웹 서버"에게 요청하는 건 크게 두가지로 나눌 수 있는데, 정적인 컨텐츠와 동적인 컨텐츠다.
찾아보면, "웹 서버"는 "정적인" 컨텐츠만 다룰 수 있고 "동적인" 컨텐츠는 "웹 애플리케이션 서버(WAS)" 만이 다룰 수 있다고 되어있다.
정적이든 동적이든 다 다뤄서 클라이언트에게 줄 수 있어야 하는 게 웹 서버라고 했는데, 웹 서버는 정적인 컨텐츠만 다룰 수 있다니 이게 뭔 소린가 했다. 돌고 돌아 한마디로 정의하면, 클라이언트 - 서버 할때의 서버는 통상적으로 "작은 의미에서의 웹 서버"와 "웹 어플리케이션 서버"를 모두 통합하여 칭하는 것이다. 그러면 도대체 왜 동적인 부분에 대한 서버는 작은 의미에서의 웹서버의 개념에 포함이 안 되어 있는 걸까? 그 이유는 웹 서버의 역사와 관련되어 있다.
초창기 서버는 정적인 데이터만 다룰 줄 알았다. 그게 곧 웹 서버였다. 그런데 시간이 지나면서 동적인 컨텐츠도 다룰 수 있을 필요성에 의해 서버를 도와주는 개념인 웹 앱 서버가 생겨났다. 서버의 뒤에 붙어서 동적인 작업을 해서 다시 서버에게 주는 식으로 쓰였다. 그렇게 점차 웹 앱 서버는 웹 서버로부터 떼려야 뗄 수 없는 관계가 되었고, 이 시점에서는 실상 웹 서버의 일부처럼 되었다. 그래서 현대의 웹에서 클라이언트의 요청을 다루는 '서버'의 개념은 고전적 의미의 웹 서버와 웹 앱 서버를 둘 다 포함하는 것이다.
이러니까 언제는 좁은 의미에서의 웹 서버(또는 고전적 의미)를, 언제는 넓은 의미에서의 웹 서버(혹은 현대적 의미)를 같은 이름으로 부르게 되고, 듣는 사람은 헷갈린 거다. 이제는 이 둘의 의미를 자명하게 구분할 수 있다.
- 넓은 의미에서의 서버: 클라이언트의 요청을 처리하고 응답을 제공하는 모든 컴퓨터 시스템. 아래 두개를 포함함. 예시로는 Spring Boot (내장된 웹 서버와 함께 동작하여 HTTP 요청을 처리하고, 정적 및 동적 컨텐츠를 모두 제공함), Node.js, Django 등이 있음.
- 좁은 의미에서의 서버:
- 정적 컨텐츠 (HTML, CSS, JS, 이미지)를 제공하고, 필요하면 HTTP 요청을 앱 서버로 전달.
- 예시: Nginx, Apache HTTP Server
- 웹 애플리케이션 서버 (WAS):
- 동적 컨텐츠 (서블릿, JSP 등) 생성하고, 비즈니스 로직 처리 및 DB 상호작용.
- 예시: Apache Tomcat
- 좁은 의미에서의 서버:
API란?
API는 Application Programming Interface의 약자로, 앱끼리 상호작용할 수 있는 인터페이스를 의미함. 소프트웨어 간에 기능이나 데이터를 주고받기 위한 명확한 규칙과 정의를 제공함.
종류로는 웹 API (REST API 혹은 GraphQL 등), SOAP API, 라이브러리 API, 운영체제 API 등이 있음. 이때 웹 API 중에 RESTful API는 많이 들어봤듯 중요한 개념이니까 짚고 넘어가자.
API를 왜 써?
예를 들어 클라이언트에서 서버에게 어떤 상품의 현재 남은 재고를 물어보고 싶어. 그러면 알고 싶을 때마다 그 코드를 작성해야해? 심지어 같은 상품도 아니고 쿠팡 뭐 이런 데는 몇십만, 몇백만 개의 상품이 있는데 그때마다? 이때 이제 그렇게 작동하는 코드를 만들고 이걸 "이 상품의 남은 재고를 물어보는 코드"라고 이름붙여두면 나중에 그냥 갖다 쓰면 되잖아. 즉, 재사용성이 좋다. 그리고 이걸 활용해서 또 다른 API를 쓸 수 있고 (확장성), 나중에 만약 수정이 필요한 경우에도 그 코드의 일부만 수정하면 전체에 적용이 되니까 유지보수도 좋고.
저런 재고 묻는 이런 기능도 가능하지만, 인증 및 권한 부여 같은 보안 관련 매커니즘에도 활용할 수 있어.
기본적으로는 CRUD - 데이터를 저장하고, 읽고, 수정하고, 삭제하는 역할을 하는 API가 웹 서버에서 주로 사용돼.
일단 웹 API가 어떻게 생겼어?
1 엔드포인트: API가 요청을 수신하는 URL. ex) https://api.example.com/users
2 프로토콜은 HTTP, HTTPS 부터 시작해서 WebSocket, SOAP 등 중에 골라서 하나 씀.
3 요청과 응답 형식: 주로 JSON 혹은 XML 형식
4 헤더: 요청과 응답에 대한 메타데이터 포함. 예를 들면 인증 정보, 컨텐츠 타입
5 문서화: 어떤 API를 만들면 무조건 그에 대한 문서도 작성해야 하므로 (마치 git repo의 readme처럼) 이것도 일부라고 생각하자.
REST(Representational State Transfer)-ful API?
웹 API 중 가장 널리 사용되는 종류. 이 특징을 잘 기억해두자.
1 모든 것을 데이터로 간주하고, 각 자원은 고유한 URI(Uniform Resource Identifier)로 이름붙임.
예를 들어, https://api.example.com/items/1 에서 items/1이라는 URI는 아이템 1번을 의미함. 그에 대한 정보가 있는 것.
2 HTTP 메서드 사용
HTTP 프로토콜을 사용하고, HTTP 메서드 중에서는 GET, POST, PUT, DELETE 그리고 PATCH 정도까지 사용함.
3 표현(Representation)은 JSON으로 주로 함 (XML로 하기도 하는데).
클라이언트와 서버 간의 메시지로 교환됨. 일반화하면, 클라이언트는 자원의 표현을 요청하고, 서버는 자원의 현재 상태를 반환함. 자꾸 표현표현 거리는데 표현이라는 용어가 더 헷갈리게 하므로, 본질을 더 정확히 기억하자.
4 무상태 Stateless
각 요청은 독립적이며, 요청 간에 서버가 클라이언트의 상태를 저장하지 않음. 모든 상태 정보는 요청에 포함되어야 함.
5 캐시 가능
응답은, 필요한 경우 구조를 변경하는 한이 있더라도 캐시할 수 있어야 함. 평소에도 무조건 가능해야 한다는 건 아니고, 필요한 경우 바꿀 수 있게 여지를 두고 설계해야된다는 뜻.
캐시 가능여부는 HTTP 헤더를 통해 가능여부를 명시함.
'백엔드 잡학사전' 카테고리의 다른 글
[스프링 입문] 스프링에서의 DB 접근 기술 (0) | 2024.08.11 |
---|---|
[스프링 입문] 스프링 빈과 의존관계 & MVC 개발하기 예시 (0) | 2024.08.10 |
[스프링 입문] 회원 관리 예제의 백엔드 개발 & 의존성 주입 (0) | 2024.08.10 |
[스프링 입문] 정적 컨텐츠와 MVC, 템플릿 엔진 (0) | 2024.08.03 |
[스프링 입문] 스프링 관련 기본 개념들 (0) | 2024.08.02 |