[Network] 네트워크 기초

sywoo0109·2023년 7월 14일
0

Network

목록 보기
1/4
post-thumbnail

  흔히 네트워크라는 단어를 자주 사용하지만 정확히 어떤 의미인지 모르고 사용하는 경우가 많다. 네트워크란 컴퓨터 혹은 기타 장치들이 서로 연결되어 데이터를 주고 받을 수 있는 시스템을 의미한다. 보통 집에서 사용하는 인터넷 공유기도 집 안에서 사용하는 다양한 기기들을 인터넷과 연결해주기 위한 도구이자 하나의 네트워크이며 기업에서 사용하는 로컬 네트워크나 인터넷 그 자체도 전 세계의 컴퓨터나 장치들을 연결해서 정보와 서비스를 교환할 수 있게 해주는 네트워크이다. 네트워크를 사용하는 목적은 데이터를 효율적으로 전송하고 공유하기 위함이다. 이를 위해 데이터를 패킷이라는 작은 단위로 분할해서 전송하며 데이터 전송을 위한 프로토콜을 사용하여 통신 규칙을 정의하고 오류 검출 및 복구, 암호화, 인증 등의 다양한 영역이 존재한다. 이번 포스트에서는 네트워크의 기본적인 지식에 대해서 작성해보려고 한다.

1. 웹 어플리케이션 아키텍처

  만약에 웹 어플리케이션을 인터넷 없이 실행시키면 어떻게 될까? 당연하지만 정상적으로 동작하지 않을 것이다. 하지만 여태 포스트를 작성하면서 썼던 간단한 자바스크립트 코드들은 인터넷 연결 없이도 동작할 수 있다. 이는 웹 어플리케이션들은 정보를 인터넷 어딘가에 존재하는 서버로부터 받아오고 있기 때문이다. 이처럼 리소스가 존재하는 곳과 그것을 사용하는 곳을 분리시키는 것을 2티어 아키텍쳐 혹은 클라이언트-서버 아키텍쳐라고 부른다. 리소스를 사용하는 곳이 클라이언트 리소스를 제공하는 곳이 서버이다. 그렇다면 왜 리소스를 제공하는 서버과 그것을 사용하는 클라이언트을 분리해놓았을까? 만약 서버가 없다면 리소스에 새로운 정보를 추가하거나 기존 정보 변경 및 삭제를 해야할 때도 어플리케이션 전체를 업데이트 해야만 하기 때문에 실시간으로 서비스를 운영하기 매우 어렵다. 또한 결제와 같은 서비스는 금전 정보를 주고 받는 은행 서버와의 연결이 필요할테니 사실상 구현할 수 있는 기능들도 매우 제한적이 될 수 밖에 없다.

  일반적으로 서버는 리소스를 전달하기만 하고 리소스를 저장하는 별도의 공간을 마련하는데 이를 데이터베이스라고 부르며 이것까지 합쳐서 3티어 아키텍처가 실제 서비스에서 가장 많이 사용되는 아키텍처라고 할 수 있다. 소위 프론트엔드라고 하는 영역이 바로 클라이언트를 개발하는 부분이고 서버와 데이터베이스를 구축하고 관리하는 영역을 백엔드라고 부르게 된다.

  그렇다면 클라이언트와 서버는 어떤 방식으로 통신을 할 수 있을까? 일반적으로 클라이언트에서 요청을 하면 서버에서는 해당 요청에 맞는 응답과 리소스를 전달하게 되며 이때 정해진 통신 규약을 프로토콜이라고 부른다. HTTP(Hypertext Transfer Protocol)는 이때 사용되는 프로토콜의 일종으로 웹에서 HTML, JSON 등의 정보를 주고받기 위한 프로토콜이라 아주 기초적이면서 자주 활용되는 프로토콜이며 HTTPS는 HTTP에서 보안 소켓 계층이나 전송 계층 보안 프로토콜을 추가적으로 사용해서 데이터를 암호화하고 인증할 수 있기 때문에 보안이 강화된 프로토콜이다. 대부분의 웹 사이트의 주소가 https://... 와 같은 방식으로 시작할텐데 이것이 바로 해당 웹 사이트의 프로토콜을 의미하는 것이다.

  하지만 통신 규약만 알고 있다고 서버와의 통신이 가능한 것은 아니다. 서버에서 어떤 요청을 지원하고 있고 그 요청을 했을 때 어떤 데이터를 반환하는지를 알고 있어야 정확히 원하는 데이터를 얻을 수 있다. 하지만 클라이언트 개발자 입장에서는 서버가 어떻게 구현되어 있는지 파악하기 힘들다. 그래서 제공되는 것이 바로 API(Application Programming Interface)이다. API는 HTTP 프로토콜을 사용해서 어떤 주소로 접근할 수 있는지, 그리고 해당 주소로 접근하면 어떤 데이터를 반환하는지를 알려주는 일종의 메뉴판과 같은 인터페이스이다.

  위의 사진은 Korean JSON에서 제공하고 있는 API의 일부이다. 이처럼 특정 엔드 포인트에 필요한 파라미터를 적용한 뒤 원하는 메서드를 사용한다면 필요한 데이터를 조회하거나 추가, 갱신, 삭제 등의 CRUD가 가능하다.

2. 브라우저의 작동 원리

  브라우저란 인터넷에서 웹 페이지를 표시하고 탐색할 수 있는 소프트웨어이다. 일반적인 사용자에게는 브라우저를 사용해서 웹을 탐색하고 웹 서핑, 이메일, 쇼핑 등의 온라인 활동을 할 수 있는 것으로 충분하지만 웹 개발자라면 브라우저가 어떻게 작동하고 있는지를 파악하는 것이 네트워크의 기초적인 부분을 이해하는데 도움을 준다.

1. URL과 URI

  브라우저에 보면 주소창이 있을 것이다. 이 주소창에 입력한 URL은 서버가 제공되는 환경에 존재하는 파일의 위치를 나타낸다. URL이란 Uniform Resource Locator의 줄임말로, 네트워크 상에서 웹 페이지, 이미지 등의 파일이 위치한 정보를 나타낸다. 웹 사이트에서 어떤 기능을 사용하기 위해서 계속 들어가게 되면 슬래시(/)가 추가되면서 안쪽으로 들어갈 수 있는데 이는 마치 CLI 환경에서 폴더와 파일의 위치를 찾아 이동하는 것과 같은 원리이다. 이 URL을 분리해서 보면 scheme, hosts, url-path로 구분할 수 있다. scheme은 앞서 웹 사이트의 주소가 https://... 와 같은 방식으로 시작한다고 언급한 것과 통신 프로토콜을 의미하는 부분이다. hosts는 웹 페이지나 이미지 등의 파일이 위치한 웹 서버, 도메인 혹은 IP를 의미하는 부분이며 url-path는 웹 서버에서 지정한 루트 디렉토리부터 실제 파일의 위치까지의 경로를 의미하게 된다. URI는 Uniform Resource Identifier의 줄임말 URL에서 한 층 더 나아가서 query, fragment를 포함하는 개념이다. query란 웹 서버에 전달하는 일종의 추가 질문과 같은 것으로 위에서 언급한 엔드 포인트에 추가하는 파라미터 등을 의미한다. 마지막으로 fragment는 일종의 북마크 기능을 수행하며 #와 특정 HTML 요소의 id를 전달하면 해당 요소가 있는 곳으로 스크롤이 이동되는 기능이다. 예를 들어서 구글에서 HTTPS를 검색한다면 https://www.google.com/search?q=HTTPS와 같은 URL이 브라우저의 주소창에 뜨는 것을 확인할 수 있다. 여기서 scheme은 https://, hosts는 www.google.com, url-path는 search, query는 ?q=HTTPS 것이다.

2. IP와 포트

  특정 웹 페이지를 찾아가기 위해서는 해당 웹 페이지의 주소를 알아야 한다. 똑같이 네트워크에 연결된 다른 장치에 접속하는 것도 가능하며 이 장치의 주소를 나타내는 체계를 IP 주소(Internet Protocol address)라고 한다. 127.0.0.1과 같은 IP 주소를 본 적이 있을텐데 이는 현재 사용 중인 로컬 PC를 지칭하는 이미 용도가 정해진 IP 주소이다. 127.0.0.1처럼 .으로 구분된 4개의 조각으로 표현되어 있는 IP 주소를 IPv4라고 하며 각 조각이 0-255의 숫자를 가질 수 있어 최대 2의 32승인 약 43억개의 주소를 표현할 수 있다. 최근에는 더 많은 기기들이 인터넷에 접속할 수 있게 되면서 이 표현 범위를 넘어서게 되면서 16비트 조각들을 8개 사용해서 2의 128승개의 주소를 표현할 수 있는 IPv6가 개발되었다. IPv6는 주소 고갈 문제 뿐만 아니라 보안 기능 강화, 효율적인 패킷 라우팅 등 IPv4와 비교하여 많은 개선 사항을 제공하고 있지만 보편화되기까지는 아직 시간이 필요해서 현재까지는 IPv4와 함께 운영되고 있으며 점차 전환 작업이 진행되고 있는 것으로 알려져있다.

  CRA를 통해 리액트 프로젝트를 구성하고 로컬 개발 서버를 실행하면 뒤에 :3000과 같은 숫자가 붙는 것을 알 수 있다. 이 숫자란 현재 사용하고 있는 통신 채널인 포트를 의미하는 숫자이다. 포트는 0부터 65535의 숫자로 구성되어 있으며 0-1024번까지의 포트는 주요 통신을 위한 규약에 따라 이미 정해져 있다. 예를 들어 80번 포트는 HTTP 통신을 위해, 443번 포트는 HTTPS 통신을 위한 포트이며 이런 경우는 URI에서도 생략할 수 있다. 그래서 CRA를 통해 설정된 로컬 개발 서버 실행 포트는 이런 포트들을 피해 임의로 3000번으로 지정되어 있던 것이다. 만약 다른 프로그램이 3000번 포트를 사용중인 상황에서 또 다른 프로젝트를 킨다면 해당 프로젝트는 3001번으로 실행되는 것을 확인할 수 있다. 이런 식으로 사전에 정해져있지 않은 임시 포트를 사용한다면 URI에 반드시 포트 번호를 포함해야 하며 올바른 포트를 사용해서 통신을 해야지만 데이터를 올바른 대상에 전달할 수 있다.

3. 도메인과 DNS

  위에서 IP에 대해서 설명한 것과 다르게 우리가 보통 구글이나 네이버와 같은 사이트에 접속할 때 IP 주소를 입력해서 들어가본 경험은 거의 없을 것이다. 그러나 구글이나 네이버도 IP 주소를 가지고 있다.

  이것은 구글의 IP 주소를 확인해본 결과이다. 이처럼 IPv6와 IPv4 주소 2개를 가지고 있는 것을 확인할 수 있다. 그리고 이것을 브라우저의 주소창에 입력한다면 실제로 구글 사이트에 들어갈 수도 있다. 하지만 사이트에 접속할 때마다 이 IP 주소를 입력해서 접속해야만 한다면 상상만 해도 길고 복잡할 것이다. 그래서 사용하는 것이 도메인이다. 주소창에 이 도메인을 입력하면 자동으로 연결된 IP 주소로 접근할 수 있는 것이다. DNS(Domain Name System)은 hosts에 도메인 이름을 IP 주소로 변환하거나 그 반대의 경우를 수행할 수 있도록 개발된 데이터베이스 시스템이다. DNS 덕분에 브라우저의 검색창에 도메인 이름을 입력하면 DNS가 매칭된 IP 주소를 찾아서 웹 서버로 요청을 전달해 클라이언트와 서버가 통신할 수 있도록 만들어준다.

4. AJAX

  리액트를 다루면서 SPA에 대해 설명했었다. SPA에 따라 웹 페이지의 일부분만 바꾸는 동작을 수행할 때 브라우저에서는 AJAX 기법을 사용한다. AJAX란 Asynchronous JavaScript And XMLHttpRequest의 약자로 리액트와 같은 어떤 라이브러리를 의미하는 단어가 아닌 비동기적으로 데이터를 교환하고 웹 페이지를 동적으로 업데이트하는 하는 여러 기술과 기법을 통칭해서 부르는 단어이다. 예를 들어 Fetch API등 다양한 기술을 활용해서 비동기적으로 서버와의 통신을 통해 데이터를 불러오면서 자바스크립트로 DOM을 조작해서 웹 페이지에서 원하는 부분만 바꾸는 앞서 포스팅에서 다뤘던 그 개념들이 AJAX에 포함되어 있다. 전통적인 웹 어플리케이션에서는 form 태그를 이용해 서버에 데이터를 전송하고 서버는 요청에 대한 응답으로 새로운 웹 페이지를 제공해줬다. 그래서 클라이언트에서 요청을 보낸다는 것은 즉 매번 새로운 페이지로 이동한다는 것을 의미하기도 했다. 그러나 Fetch API를 사용하면서 서버와의 비동기적인 통신이 가능해졌고 자바스크립트에서 DOM을 사용해서 웹 페이지를 변경할 수 있게 되면서 SPA라는 개념을 실현할 수 있게 되었다.

  AJAX의 장단점은 사실 앞에서 AJAX에 포함된 기술들을 설명하면서 이미 다 설명하긴 했었다. 장점으로는 서버에서는 더 이상 완성된 HTML 파일을 전송하지 않아도 되기 때문에 필요한 데이터가 전체 HTML 문서에서 JSON과 같은 텍스트 정도로 줄어들었다. 따라서 더 많은 상호작용을 넣으면서도 더 빠른 웹 어플리케이션을 제작할 수 있게 되었다. 한편 단점으로는 처음 받는 HTML 문서에 내용의 거의 없기 때문에 검색 엔진 최적화에 불리하다는 점이 있다. 또 AJAX 만으로는 이전 상태 같은 것은 기억하지 않기 때문에 뒤로가기 버튼 등이 제대로 동작하지 않는다는 점이 있긴 한데 만약 리액트를 사용한다면 SPA를 구현하기 위해 React Router와 같은 라이브러리를 사용할 확률이 매우 높고 이것이 Hisory API를 사용하여 경로를 관리하기 때문에 딱히 신경써야할 문제는 아니다.

5. SSR과 CSR

  SSR과 CSR은 어디에서 웹 어플리케이션의 페이지 렌더링 방법을 나타내는 용어이다. 우선 SSR은 Server Side Rendering의 줄임말로 서버 측에서 페이지의 초기 렌더링을 수행하는 방법이다. 브라우저에서 요청을 보내면 서버는 요청된 페이지의 HTML, CSS 및 자바스크립트와 같은 필요한 리소스를 생성하여 클라이언트에게 전달한다. 클라이언트는 이를 받아 페이지를 렌더링하고, 사용자의 상호작용으로 인해 추가적인 데이터가 필요해지면 서버는 앞에서 말한 작업을 그대로 다시 수행하게 된다. SSR은 초기 페이지 로딩 속도가 빠르고, 검색 엔진 최적화에 유리하지만 서버의 부하가 증가할 수 있으며 동적인 상호작용에 대해서는 추가적인 네트워크 요청이 필요할 수도 있다는 단점이 있다.

  한편 CSR은 Client Side Rendering 의 줄임말로 클라이언트 측에서 페이지의 렌더링을 수행하는 방법이다. 클라이언트가 서버에 초기 페이지를 요청하면, 서버는 정적인 HTML, CSS 및 자바스크립트 파일을 전달한다. 이후 클라이언트에서 자바스크립트를 사용하여 페이지를 동적으로 렌더링하고 데이터를 가져와 화면을 업데이트합니다. 사용자의 상호작용으로 인해 추가적인 데이터가 필요해지면 Fetch API와 같은 기술을 사용해서 필요한 데이터만을 서버에 요청하게 되며 브라우저에서 해당 정보로 페이지를 다시 렌더링한다. CSR의 경우 웹 페이지에 동적인 상호작용이 많은 경우 유리하고 서버의 부하가 상대적으로 낮다. 한편 초기 페이지 로딩 시간이 오래 걸릴 수 있고 검색 엔진 최적화에 불리하다는 단점이 있다.

  일반적으로 검색 엔진 최적화를 통해서 검색 결과의 상단에 해당 서비스가 노출되는 것이 서비스 기획의 우선순위인 경우 SSR 방식을 선택하는 경우가 많고 웹 사이트에 상호작용이 많은 경우는 CSR을 선택하는 편이 유리하다고 알려져있다. 사실 프론트엔드 개발자는 이것과 관련된 코드를 직접 작성하지 않지만 개발하고 있는 서비스의 특징에 따라서 어떤 방식을 선택하는 편이 좋은지 알고 있는 것이 도움이 될 일이 있을 것이다.

3. HTTP

  지금까지 네트워크에 관한 기초 정보들을 알아봤다. 마지막으로는 간단한게 HTTP 프로토콜에 따른 실제 요청과 응답이 어떻게 이루어지는지 간단하게 살펴보려고 한다. 클라이언트가 서버에게 하는 요청과 서버가 클라이언트에게 돌려주는 응답 모두 HTTP Messages라고 한다. HTTP Messages는 몇 줄의 텍스트 정보로 구성되어 있지만 개발자가 이걸 직접 작성할 필요는 없고 주로 구성 파일이나 API, 기타 인터페이스에서 자동으로 완성한다. 간단한 예시를 통해 HTTP Messages 구조를 알아보자.

  요청과 응답 모두 구조 자체는 유사하다. 가장 첫 줄은 start line으로 요청의 상태를 나타낸다. HTTP 요청 메세지에는 요청 메서드와 요청 대상의 URL 및 HTTP 프로토콜 버전이 적혀있고 HTTP 응답 메세지에는 상태 코드와 상태 메세지 그리고 HTTP 프로토콜 버전이 적혀있다. 그 다음엔 HTTP headers는 요청을 지정하거나 메세지에 포함된 본문을 설명하는 헤더의 집합이다. 그 다음 헤더와 본문을 구분하기 위해 한 칸의 빈줄이 있은 다음 body에 상황에 따라 요청이나 응답과 관련된 데이터나 문서가 들어가 있을 수 있다.

  중요한 것은 HTTP는 무상태 프로토콜이라는 점을 기억해야 한다는 것이다. HTTP 프로토콜 자체는 어떠한 상태 정보도 유지하지 않기 때문에 현재 요청에서 이전 요청의 정보를 알 수 없다는 것이다. 서버에서는 클라이언트의 세션 데이터나 인증 상태 등의 상태 정보를 애초에 저장하지 않는다. 그래서 클라이언트에서 각 요청에 필요한 모든 상태 정보를 제공해야 하며 주로 쿠키나 세션 토큰 등을 인증 헤더에 넣는 방식으로 인증 상태를 확인할 수 있다. 쿠키나 토큰에 관한 내용을 추후에 다른 포스트에서 본격적으로 다루려고 한다.

0개의 댓글