Networks

OSI 7계층, TCP/IP, HTTP, 라우팅, 소켓 프로그래밍

OSI 7계층

✨ OSI 7 계층을 나누는 이유는 무엇일까?

중요한 목적은 표준과 학습 도구라 할 수 있다.

표준화를 통해 이질적인 포트 문제나 프로토콜 등으로 인한 문제를 해결하여 비용을 절감했다.

또한, 계층별의 기능과 통신 과정을 단계별로 나누어서 쉽게 알 수 있고, 특정한 곳에 이상이 생기면 그 단계만 수정할 수 있기 때문에 편리하다.

1) 물리(Physical)

리피터, 케이블, 허브 등

주로 전기적, 기계적, 기능적인 특성을 이용해서 통신 케이블로 데이터를 전송하는 역할을 한다.

3) 네트워크(Network)

라우터, IP

여러 개의 노드를 거칠 때마다 경로를 찾아주는 역할을 하며, 다양한 길이의 데이터를 목적지까지 가장 안전하고 빠르게 전달하는 기능을 담당한다. (전송 계층이 요구하는 서비스 품질을 제공하기 위한 기능적, 절차적 수단을 제공한다.)

라우터를 통해 이동할 경로를 선택하여 IP 주소를 지정하고, 해당 경로에 따라 패킷을 전달해준다.

라우팅, 흐름 제어, 오류 제어, 세그먼테이션 등을 수행한다.

4) 전송 계층(Transport)

TCP, UDP

TCP, UDP 프로토콜을 통해 통신을 활성화 한다. 포트를 열어두고, 프로그램들이 전송을 할 수 있도록 제공해준다. 이를 통해 양 끝 단의 사용자들이 데이터를 주고 받을 수 있다.

  • TCP : 신뢰성, 연결 지향적

  • UDP : 비신뢰성, 비연결성, 실시간

5)세션(Session)

API, Socket

양 끝 단의 응용 프로세스가 통신을 관리하기 위한 방법을 제공한다.

데이터가 통신하기 위한 논리적 연결을 담당한다.

TCP/IP 세션을 만들고 없애는 책임을 지니고 있다.

6) 표현(Presentation)

JPEG, MPEG 등

데이터 표현에 대한 독립성을 제공하고 암호화하는 역할을 담당한다.

코드 간의 번역을 담당하여 사용자 시스템에서 데이터의 형식상 차이를 다루는 부담을 응용 계층으로부터 덜어준다.

파일 인코딩, 명령어를 포장, 압축, 암호화한다.

7) 응용(Application)

HTTP, FTP, DNS 등

최종 목적지로 응용 프로세스와 직접 관계하여 일반적인 응용 서비스를 수행한다.

사용자 인터페이스, 전자우편, 데이터베이스 관리 등의 서비스를 제공한다.

TCP/IP : 흐름제어, 혼잡제어

TCP

  • 일반적으로 TCP와 IP를 함께 사용하는데, IP가 데이터의 배달을 처리한다면 TCP는 패킷을 추적 및 관리한다.

  • 신뢰성 있는 데이터 전송을 지원하는 연결 지향형 프로토콜이다.

  • 사전에 3-way handshake라는 과정을 통해 연결을 설정하고 통신을 시작한다.

  • 4-way handshake 과정을 통해 연결을 해제(가상 회선 방식)한다.

  • 흐름 제어, 혼잡 제어, 오류 제어를 통해 신뢰성을 보장한다. 그러나 이 때문에 UDP보다 전송 속도가 느리다는 단점이 있다.

  • 데이터의 전송 순서를 보장하며 수신 여부를 확인할 수 있다.

  • TCP를 사용하는 예로는 대부분의 웹 HTTP 통신, 이메일, 파일 전송에 사용된다.

  • TCP가 가상회선 방식을 제공한다는 것은 송신측과 수신측을 연결하여 패킷을 전송하기 위한 논리적 경로를 배정한다는 뜻이다.

패킷(Packet)?

  • 인터넷 내에서 데이터를 보내기 위한 경로 배정(라우팅)을 효율적으로 하기 위해서 데이터를 여러 개의 조각으로 나누어 전송을 하는데, 이때 조각을 패킷이라고 한다.

TCP는 패킷을 어떻게 추적 및 관리하는가?

  • 데이터는 패킷 단위로 나누어 같은 목적지(IP 계층)으로 전송된다.

Ex) 한 줄로 서야 하는 A,B,C라는 사람(패킷)이 서울(송신측)에서 출발하여 부산(수신측)으로 가야한다고 가정하다.

A,B,C가 순차적으로 가는 상황에서 B가 길을 잘못 들어서 분실되었다.

하지만 목적지에서는 A,B,C가 모두 필요한지 모르고 A,C만 보고 다 왔다고 착각할 수 있다. 그렇기 때문에 A,B,C라는 패킷에 1,2,3이라는 번호를 부여하여 패킷의 분실 확인 처리를 하기 위해 목적지에서 패킷을 재조립한다.

이런 방식으로 TCP는 패킷을 추적하며, 나누어 보내진 데이터를 목적지에서 받고 재조립할 수 있게 된다.

흐름 제어

  • 송신측과 수신측 사이의 데이터 처리 속도 차이(흐름)을 해결하기 위한 기법.

  • 만약, 송신측의 전송량 > 수신측의 처리량일 경우 전송된 패킷은 수신측의 큐를 넘어서 손실될 수 있기 때문에 송신측의 패킷 전송량을 제어하게 된다.

  1. Stop and Wait(정지 - 대기)

  • 매번 전송한 패킷에 대한 확인 응답을 받아야 그 다음 패킷을 전송할 수 있다.

  • 이러한 구조 때문에 비효율적이다. (단점)

  • Give & Take.

  1. Sliding Window(슬라이딩 윈도우)

  • (송신측 = 전송측)

  • 수신측에서 설정한 윈도우 크기만큼 송신측에서 확인 응답 없이 세그먼트를 전송할 수 있게 하여 데이터 흐름을 동적으로 조절하는 기법이다.

  • 윈도우 : 송신, 수신 스테이션 양쪽에서 만들어진 버퍼의 크기.

  • Stop and Wait의 비효율성을 개선한 기법

  • 송신측에서는 Ack 프레임을 수신하지 않더라도 여러 개의 프레임을 연속적으로 전송할 수 있다.

  • 송신측에서 0,1,2,3,4,5,6을 보낼 수 있는 프레임을 가지고 있고 데이터 0,1을 전송했다고 가정하면 슬라이딩 윈도우의 구조는 2,3,4,5,6처럼 변하게 된다.

  • 이때, 만약 수신측으로부터 ACK라는 프레임을 받게 된다면 송신측은 이전에 보낸 데이터 0,1을 수신측에서 정상적으로 받았음을 알게 되고 송신측의 슬라이딩 윈도우는 ACK 프레임에 따른 프레임의 수만큼 오른쪽으로 경계가 확장된다.

오류 제어

  • 오류 검출과 재전송을 포함한다.

  • ARQ(Automatic Repeat Request) 기법을 사용해 프레임이 손상되었거나 손실되었을 경우, 재전송을 통해 오류를 복구한다.

  • ARQ 기법은 흐름 제어 기법과 관련되어 있다.

  1. Stop and Wait ARQ

  • 송신측에서 1개의 프레임을 송신하고, 수신측에서 수신된 프레임의 에러 유무 판단에 따라 ACK or NAK를 보내는 방식이다.

  • 식별을 위해 데이터 프레임과 ACK 프레임은 각가 0,1 번호를 번갈아가며 부여한다.

  • 수신측이 데이터를 받지 못했을 경우, NAK를 보내고 NAK를 받은 송신측은 데이터를 재전송한다.

  • 만약, 데이터나 ACK가 분실되었을 경우 일정 간격의 시간을 두고 타임아웃이 되면, 송신측은 데이터를 재전송한다.

  1. Go-Back-n ARQ(슬라이딩 윈도우)

  • 전송된 프레임이 손상되거나 분실된 경우 그리고 ACK 패킷의 손실로 인한 TIME_OUT이 발생한 경우, 확인된 마지막 프레임 이후로 모든 프레임을 재전송한다.

  • 슬라이딩 윈도우는 연속적인 프레임 전송 기법으로 전송측은 전송된 모든 프레임의 복사본을 가지고 있어야 하며, ACK와 NAK 모두 각각 구별해야 한다.

  • ACK : 다음 프레임을 전송.

  • NAK : 손상된 프레임 자체 번호를 반환.

[재전송 되는 경우]

(1). NAK 프레임을 받았을 경우.

  • 만약, 수신측으로 0~5까지의 데이터를 보냈다고 가정하자.

  • 수신측에서 데이터를 받았음을 확인하는 ACK 프레임을 중간 중간 보내게 되며, ACK 프레임을 확인한 전송측은 계속해서 데이터를 전송한다.

  • 그러나 만약 수신측에서 데이터 오류 프레임 2를 발견하고 NAK2를 전송측에 보낸다고 해보자.

  • NAK2를 받은 전송측은 데이터 프레임 2가 잘못되었다는 것을 알고 데이터를 재전송한다.

  • GBn ARQ의 특징은 데이터를 재전송하는 부분이다. NAK(n)를 받아 n 데이터 이후의 모든 데이터를 재전송한다.

(2). 전송 데이터 프레임의 분실

  • GBn ARQ의 특징은 확인된 데이터 이후의 모든 데이터 프레임 재전송과 수신측의 폐기이다.

  • 수신측에서 데이터 1을 받고 다음 데이터로 3을 받게 된다면 데이터 2를 받지 못했으므로 수신측에서는 데이터 3을 폐기하고 데이터 2를 받지 못했다는 NAK2를 전송측에 보낸다.

  • NAK를 받은 전송측은 (1) 경우와 같이 NAK(n) 데이터로부터 모든 데이터를 재전송하며 수신측은 기존에 받았던 데이터 중 NAK(n)으로 보냈던 대상 데이터 이후의 모든 데이터를 폐기하고 재전송 받는다.

https://user-images.githubusercontent.com/33534771/75339152-507e0000-58d3-11ea-876e-e29653f9f99e.png

(3). 지정된 타임 아웃 내의 ACK 프레임 분실(Lost ACK)

  • 전송측은 분실된 ACK를 다루기 위해 타이머를 가지고 있다.

  • 전송측에서는 이 타이머의 타임 아웃 동안 수신측으로부터 ACK 데이터를 받지 못했을 경우, 마지막 ACK된 데이터부터 재전송한다.

https://user-images.githubusercontent.com/33534771/75339203-6ab7de00-58d3-11ea-973d-a4db4abf52a5.png
  • 전송측은 NAK ㅍ프레임을 받았을 경우, NAK 프레임 번호부터 데이터를 재전송한다.

  • 수신측은 원하는 프레임이 아닐 경우, 데이터를 모두 폐기 처리한다.

  • 타임아웃(ACK 분실)의 경우, 마지막 ACK된 데이터부터 재전송한다.

  1. SR(Selective-Reject) ARQ

  • GBn ARQ의 확인된 마지막 프레임 이후의 모든 프레임을 재전송하는 단점을 보완한 기법이다.

  • SR ARQ는 손상된, 손실된 프레임만 재전송한다.

  • 그렇기 때문에 별도의 데이터 재정렬을 수행해야 하며, 별도의 버퍼를 필요로 한다.

  • 수신측에 버퍼를 두어 받은 데이터의 정렬이 필요하다.

https://user-images.githubusercontent.com/33534771/75339302-963ac880-58d3-11ea-9a7f-fe6e4a7a6f38.png

혼잡 제어

  • 송신측의 데이터 전달과 네트워크의 데이터 처리 속도를 해결하기 위한 기법이다.

  • 한 라우터에게 데이터가 몰려 모든 데이터를 처리할 수 없는 경우, 호스트들은 재전송을 하게 되고 결국 혼잡만 가중시켜 오버플로우나 데이터 손실이 발생한다.

  • 이러한 네트워크의 혼잡을 피하기 위해 송신측에서 보내는 데이터의 전송 속도를 제어하는 것이 혼잡 제어의 개념이다.

  1. AIMD(Additive Increase Multicative Decrease)

  • 합 증가 / 곱 감소 알고리즘이라고 한다.

  • 처음에 패킷 하나를 보내는 것으로 시작하여 전송한 패킷이 문제 없이 도착한다면 Window Size를 1씩 증가시키며 전송하는 방법이다. 만약, 패킷 전송을 실패하거나 TIME_OUT이 발생하면 Window Size를 절반으로 감소시킨다.

  • 이 방식은 공평하다.

    • 여러 호스트가 한 네트워크를 공유하고 있으면 나중에 진입하는 쪽이 처음에는 불리하지만, 시간이 흐르면 평형 상태로 수렴하게 되는 특징이 있다.

  • 문제점은 초기 네트워크의 높은 대역폭을 사용하지 못하고 네트워크가 혼잡해지는 상황을 미리 감지하지 못하여 혼잡해지고 나서야 대역폭을 줄이는 방식이다.

  1. Slow Start

  • AIMD가 네트워크의 수용량 주변에서는 효율적으로 동작하지만, 처음에 전송 속도를 올리는 데 시간이 너무 길다는 단점이 있다.

  • Slow Start는 AIMD와 마찬가지로 패킷을 하나씩 보내는 것부터 시작한다. 이 방식은 패킷이 문제 없이 도착하면 각각의 ACK 패킷마다 Window Size를 1씩 늘린다. 즉, 한 주기가 지나면 Window Size는 2배가 된다.

  • 따라서 그래프의 모양은 지수 함수 꼴이 된다.

  • 혼잡 현상이 발생하면 Window Size를 1로 떨어뜨린다.

  • 처음에는 네트워크의 수용량을 예측할 수 있는 정보가 없지만 한번 혼잡 현상이 발생하고 나면 네트워크의 수용량을 어느정도 예상할 수 있으므로 혼잡 현상이 발생하였던 Window Size의 절반까지는 이전처럼 지수 함수 꼴로 Window Size를 증가시키고 그 이후부터는 완만하게 1씩 증가시키는 방식이다.

https://user-images.githubusercontent.com/33534771/75339337-a6eb3e80-58d3-11ea-8ff1-b99bcc992fca.png
  • 미리 정해진 임계값(threshold)에 도달할 때까지 윈도우의 크기를 2배씩 증가시킨다.

  • Slow Start라는 이름을 사용하지만, 매 전송마다 2배씩 증가하기 때문에 전송되어지는 데이터의 크기는 지수함수적으로 증가한다.

  • 전송되는 데이터의 크기가 임계 값에 도달하면 혼잡 회피 단계로 넘어간다.

https://user-images.githubusercontent.com/33534771/75339370-bb2f3b80-58d3-11ea-9211-af3ca1e5960b.png

[혼잡 회피(Congestion Avoidance)]

  • 윈도우의 크기가 임계 값에 도달한 이후에는 데이터의 손실이 발생할 확률이 높아진다.

  • 따라서 이를 회피하기 위해 윈도우 크기를 선형적으로 1씩 증가시키는 방법이다.

  • 수신측으로부터 일정 시간 동안까지 ACK를 수신하지 못하는 경우.

    • 타임 아웃의 발생 : 네트워크 혼잡이 발생했다고 인식.

    • 혼잡 상태로 인식된 경우

      • 윈도우의 크기를 즉, 세그먼트의 수를 1로 감소시킨다.

      • 동시에 임계값을 패킷 손실이 발생했을 때의 윈도우 크기의 절반으로 줄인다.

[빠른 회복(Fast Recovery)]

  • 혼잡한 상태가 되면 Window Size를 1로 줄이지 않고 절반으로 줄이고 선형 증가시키는 방법이다.

  • 빠른 회복 정책까지 적용하면 혼잡 상황을 한번 겪고 나서부터는 순수한 AIMD 방식으로 동작하게 된다.

[빠른 재전송(Fast Retransmit)]

  • 수신측에서 패킷을 받을 때 먼저 도착해야 할 패킷이 도착하지 않고 다음 패킷이 도착한 경우에도 ACK 패킷을 보낸다. 단, 순서대로 잘 도착한 마지막 패킷의 다음 패킷의 순번을 ACK 패킷에 실어서 보낸다. 따라서 중간에 패킷 하나가 손실되면 송신측에서는 순번이 중복된 ACK 패킷을 받게 된다. 이것을 감지하면 문제가 되는 순번의 패킷을 재전송할 수 있다.

  • 빠른 재전송은 중복된 순번의 패킷을 3개(3 ACK) 받으면 재전송한다. 그리고 이러한 현상이 일어나는 것은 약간의 혼잡이 발생한 것으로 간주하여 Window Size를 절반으로 줄인다.

UDP

UDP

  • User Datagram Protocol의 약자이다.

  • 데이터를 데이터 그램 단위로 처리하는 프로토콜.

    • 데이터 그램 : 독립적인 관계를 지니는 패킷

  • 비연결형 프로토콜로 사전에 연결 설정 없이 데이터를 전달한다.

  • 사전에 연결 설정을 하지 않은 데이터 그램 방식을 통해 데이터를 전달하기 때문에 하나의 메시지에서 분할된 각각의 패킷은 서로 다른 경로로 전송될 수 있다.

  • 송신측에서 전송한 패킷의 순서와 수신측에 도착한 패킷의 순서가 다를 수 있다. 그러나 서로 다른 경로로 패킷을 처리함에도 불구하고 순서를 부여하거나 재조립하지 않는다.

  • 흐름 제어, 혼잡 제어, 오류 제어를 하지 않으므로 손상된 세그먼트에 대한 재전송을 하지 않는다.

  • 이로 인해 속도가 빠르며 네트워크 부하가 적다는 장점이 있지만, 신뢰성 있는 데이터 전송을 보장하지 못한다.

  • UDP는 RTP(Real Time Protocol), Multicast, DNS 등에서 사용된다

DNS 같은 경우 누군가 DNS 서비스를 요청할 때마다 TCP처럼 Session을 맺고 통신한다면 속도도 느리고, 서버 리소스도 엄청나게 소모될 것이다.

그런가 하면 NMS(Network Management Server)가 5분에 한번씩 장비 상태를 점검하기 위해 정보를 읽어오는데 수백, 수천대의 장비와 Session을 맺어야 한다면 이것도 마찬가지로 문제가 생긴다.

그렇기 때문에 UDP를 사용한다.

재전송을 하면 안되는 서비스가 있다.

대표적으로 RTP이다.

전화를 하고 있다 다고 가정해보자.

"여","보","세","요"라는 4개의 데이터를 전송했는데, "세"를 못받았다고 다시 보내달라고 하면 "여보요세"가 될 것이다.

이럴 때는 그냥 "여보X요"로 전달하는게 나은 상황이다.

또한, Multicast 서비스가 UDP를 사용한다.

1:N으로 통신하는 방식에서 한 사람이 데이터를 받지 못했다고 재전송을 요청한다고 가정해보자. 제대로 받은 사람들도 해당 데이터를 다시 받아서 처리해야 한다는 문제점이 발생할 수 있기 때문에 UDP를 사용한다.

3-Way handshake & 4-Way handshake

3 way handshake

TCP/IP 프로토콜을 이용하여 통신을 진행할 때, 두 종단 간 정확한 데이터 전송을 보장하기 위해 연결을 설정하는 과정이다.

https://user-images.githubusercontent.com/33534771/75338886-d77ea880-58d2-11ea-84c3-f8b60663f9c6.png

[연결 과정]

SYN : Synchronize Sequence Number

ACK : Acknowledgement

  1. 클라이언트는 서버에 접속을 요청하는 SYN(a) 패킷을 보낸다.

  2. 서버는 클라이언트의 요청인 SYN(a) 패킷에 대한 요청 수락 응답으로 ACK(a+1) 패킷과 클라이언트도 포트를 열어달라는 SYN(b) 패킷을 보낸다.

  3. 클라이언트는 ACK(a+1) 패킷과 SYN(b) 패킷을 받고 이에 대한 응답으로 ACK(b+1) 패킷을 보내며 연결이 성립된다.

[Q. 왜 2way가 아니라 3way일까?]

TCP양방향성 연결이기 때문에 클라이언트에서 서버에게 자신의 존재를 알리고 패킷을 보낼 수 있는 것처럼 서버에서도 클라이언트에게 자신의 존재를 알리고 패킷을 보낼 수 있다는 신호를 보내야 하기 때문이다.

[참고]

처음에 클라이언트에서 SYN 패킷을 보낼 때 Sequence Number에는 랜덤한 숫자가 담겨진다.

Connection을 맺을 때, 사용하는 포트(port)는 유한 범위 내에서 사용하고 시간이 지남에 따라 재사용한다. 따라서 이전에 사용한 포트 번호를 재사용할 가능성이 있다.

Sequence Number가 순차적인 숫자로 전송된다면 서버는 이전의 Connection으로부터 전송되는 패킷으로 인식할 수 있다. 따라서 이러한 문제를 해결하기 위해 난수로 초기 Sequence Number를 설정한다.

4 way handshake

TCP/IP 프로토콜을 이용한 통신 과정에서는 위에서 언급했던 것처럼 3 way handshake 과정을 통해 연결을 설정하고 4 way handshake 과정을 통해 연결 설정을 해제한다.

https://user-images.githubusercontent.com/33534771/75338959-ef562c80-58d2-11ea-99eb-1c09ec97e83a.png

[연결 과정]

  1. 클라이언트는 서버에게 연결을 종료하겠다는 FIN 패킷을 보낸다.

  2. 서버는 클라이언트의 요청(FIN)에 대한 응답으로 ACK 패킷을 보낸다.

2-1) 처리해야 할 자신의 통신이 끝날 때까지 기다린다.

  1. 처리해야 할 모든 통신을 끝마쳤다면 연결을 종료하겠다는 FIN 패킷을 보낸다.

  2. 클라이언트는 FIN 패킷에 대한 확인 응답으로 ACK 패킷을 보낸다.

  3. 클라이언트의 ACK 패킷을 받은 서버는 소켓 연결을 close 한다.

  4. 클라이언트는 아직 서버로부터 받지 못한 데이터가 있을 것을 대비해 기다리는 과정을 거친다.(TIME_WAIT)

[에러 발생]

클라이언트에서 FIN 패킷 전송 후 ACK 패킷을 기다리는 FIN_WAIT1과 서버의 ACK 패킷을 받은 후 FIN 패킷을 기다리는 FIN_WAIT2 에러 발생으로 인해 Time out이 되면 스스로 연결을 종료한다.

그러나, CLOSE_WAIT은 Application이 close()를 적절하게 처리하지 못하면 CLOSE_WAIT 상태로 계속 기다리게 되어 Socket Hang Up 에러가 발생할 수 있다.

HTTP

Header

Caching

Optimization

HTTP2.0

HTTP

  • 웹 서버와 클라이언트 간의 문서를 교환하기 위한 통신 규약

  • 웹에서만 사용하는 프로토콜로 TCP/IP 기반으로 서버와 클라이언트 간의 요청과 응답을 전송한다.

HTTP의 특징

  • TCP 기반의 통신 방식

  • 비연결 지향

    • 브라우저를 통해 사용자의 요청으로 서버와 접속하여 요청에 대한 응답의 데이터를 전송후, 연결을 종료한다.

    • 간단하기 때문에 자원이 적게드는 장점이 있다.

    • 하지만, 연결이 지속적이지 않기 때문에 사용자와 연결 종료후 추가적인 요청시 어떤 사용자의 요청인지 모른다는 점이 존재한다.

    • 즉, 여러 사용자가 요청할 시 각각의 사용자 요청을 구분할 수 없어서 제대로 된 응답 데이터를 전송할 수 없다는 단점이 있다.

    • 해결 방법으로는 쿠키, 세션, 히든 폼 필드 등이 있다.

  • 단방향성

    • 사용자의 요청 한개에 대해 한개의 응답을 하는 방식이기 때문에 서버가 먼저 응답하지 않는다.

HTTP의 문제점

  • HTTP는 평문 통신이기 때문에 도청이 가능하다.

  • 통신 상대를 확인하지 않기 때문에 위장이 가능하다.

  • 완전성을 증명할 수 없기 때문에 변조가 가능하다.

이러한 문제점을 해결하기 위해 HTTPS가 등장했다.

HTTPS

  • HTTP 통신하는 소켓 부분을 인터넷 상에서 정보를 암호화하는 SSL(Secure Socket Layer)라는 프로토콜로 대체한 것이다.

  • HTTP는 TCP와 통신했지만, HTTPS에서 HTTP는 SSL과 통신하고 SSL이 TCP와 통신하게 된다.

  • 즉, 하나의 레이어를 더 둔 것이다.

  • HTTPS의 SSL에서는 대칭키 암호화 방식과 공개키 암호화 방식을 모두 사용한다.

SSL

SSL 프로토콜은 Netscape 사에서 웹 서버와 브라우저 사이의 보안을 위해 만들어졌다. CA(Certificate Authority)라 불리는 서드 파티로부터 서버와 클라이언트의 인증을 하는데 사용된다.

애플리케이션 서버를 운영하는 기업은 CA를 통해 인증서를 만든다.

  1. 애플리케이션 서버를 운영하는 기업은 HTTPS 적용을 위해 공개키와 개인키를 만든다.

  2. 신뢰할 수 있는 CA 기업을 선택하고 인증서 생성을 요청한다.

  3. CA는 서버의 공개키, 암호화 방법 등의 정보를 담은 인증서를 만들고 해당 CA의 개인키로 암호화하여 서버에 제공한다.

  4. 클라이언트가 SSL로 암호화된 페이지(https://)를 요청시 서버는 인증서를 전송한다.

클라이언트와 서버의 통신 흐름 과정

  1. 클라이언트가 SSL로 암호화된 페이지를 요청한다.

  2. 서버는 클라이언트에게 인증서를 전송한다.

  3. 클라이언트는 인증서가 신용이 있는 CA로부터 서명된 것인지 판단한다. 브라우저는 CA 리스트와 해당 CA의 공개키를 가지고 있다. 공개키를 활용하여 인증서가 복호화가 가능하다면 접속한 사이트가 CA에 의해 검토되었다는 것을 의미한다. 따라서 서버가 신용이 있다고 판단한다. 공개키가 데이터를 제공한 사람의 신원을 보장해주는 것으로 이러한 것을 전자 서명 이라고 한다.

  4. 클라이언트는 CA의 공개키를 이용해 인증서를 복호화하고 서버의 공개키를 획득한다.

  5. 클라이언트는 서버의 공개키를 사용해 랜덤 대칭 암호화키, 데이터 등을 암호화하여 서버로 전송한다.

  6. 서버는 자신의 개인키를 이용해 복호화하고 랜덤 대칭 암호화키, 데이터 등을 획득한다.

  7. 서버는 랜덤 대칭 암호화키로 클라이언트 요청에 대한 응답을 암호화하여 전송한다.

  8. 클라이언트는 랜덤 대칭 암호화키를 이용해 복호화하고 데이터를 이용한다.

https://user-images.githubusercontent.com/33534771/75338777-a1d9bf80-58d2-11ea-9754-809110475c89.png

인증서에 포함된 내용

  • 서버측 공개키(public key)

  • 공개키 암호화 방법

  • 인증서를 사용한 웹서버의 URL

  • 인증서를 발행한 기관 이름

모든 웹페이지에서 HTTPS를 사용하지 않는다. 이유는 평문 통신에 비해서 암호화 통신은 CPU나 메모리 등 리소스를 많이 필요로 하기 때문이다. 통신할 때마다 암호화를 하면 리소스를 소비하기 때문에 서버 한 대당 처리할 수 있는 Request 수가 줄어들게 된다.

따라서 민감한 정보를 다룰 때만 HTTPS에 의한 암호화 통신을 사용해야 한다.

공개키 암호, 대칭키 암호

대칭키 암호화

https://user-images.githubusercontent.com/33534771/75338515-2bd55880-58d2-11ea-9fcf-1fe65c72b69d.png
  • 암호화에 사용되는 키와 복호화에 사용되는 키가 동일한 암호화 기법이다.

  • 대칭키 암호 방식으로 암호화한 정보를 누군가에게 보낼 때, 암호키도 함께 보내야 한다. 암호키 자체는 암호화가 되지 않은 평문으로 분실하거나 타인에게 노출되면 보안에 매우 취약할 수 있다.

  • 키 전달 및 관리에 어려움이 있지만, 대칭키 암호화 방식은 암호화 연산 속도가 빠르기 때문에 효율적인 암호 시스템을 구축할 수 있다는 장점이 있다.

  • 블록 암호화, 스트림 암호화가 있다.

공개키 암호화

  • 대칭키 암호화 방식의 키 전달의 취약점을 해결하기 위해 나온 방식이다. 암호화에 사용하는 키와 복호화에 사용하는 키를 분리했다. 따라서 비대칭키 암호화라고도 부른다.

  • 자신이 가지고 있는 고유한 암호키(개인키 혹은 비밀키)로만 복호화할 수 있는 암호키(공개키)를 대중에게 공개한다.

  • 공개키 암호화 방식의 진행과정

    1. B 사용자는 자신의 공개키를 공개한다. 이 공개키는 암호화에 사용되는 키이며, 누구든지 열람이 가능하다. (복호화에 사용되는 키는 B 자신만 가지고 있다. 잃어버리면 안된다.)

    2. A 사용자는 B 사용자의 공개키로 데이터를 암호화한다.

    3. 암호화된 문서를 B 사용자에게 전송한다.

    4. B 사용자는 자신만의 개인키(복호화키)를 이용하여 전송받은 암호화 문서를 복호화하여 데이터를 열람한다.

  • 대칭키 암호화 방식의 키 전달 문제를 해결했지만 암호화, 복호화를 위해 복잡한 수학 연산을 수행하기 때문에 대칭키 방식에 비해 속도가 느리고 복잡하다는 단점이 있다.

대칭키 암호화의 장점과 공개키 암호화의 장점을 채택하여 용량이 큰 정보는 대칭키로 암호화하고, 암호화에 사용된 대칭키는 공개키로 암호화하여 대상에게 전달하는 하이브리드 암호화 방법이 일반적으로 사용되고 있다.

공개키 기반 구조

특정 사람의 개인키와 공개키는 어떻게 생성할 것이며, 어떻게 배포할 것이고 어떻게 관리해야 하는가에 대한 이슈가 존재한다. 또한, 어떤 공개키가 특정한 사람의 공개키라는 것을 어떻게 보장할 수 있는지에 대한 이슈도 존재한다.

이를 해결하기 위해 디지털 인증서를 도입했고 이를 활용하는 소프트웨어, 하드웨어, 정책, 제도, 사용자 등을 총칭해서 공개키 기반 구조라고 한다.

https://user-images.githubusercontent.com/33534771/75338621-5e7f5100-58d2-11ea-8722-be41d86e0a42.png

✨ TLS/SSL HandShake

HTTPS에서 클라이언트와 서버간 통신 전 SSL 인증서로 신뢰성 여부를 판단하기 위해 연결하는 방식

https://user-images.githubusercontent.com/34904741/139517776-f2cac636-5ce5-4815-981d-33905283bf13.png

진행 순서

  1. 클라이언트는 서버에게 client hello 메시지를 담아 서버로 보낸다. 이때 암호화된 정보를 함께 담는데, 버전, 암호 알고리즘, 압축 방식 등을 담는다.

  2. 서버는 클라이언트가 보낸 암호 알고리즘과 압축 방식을 받고, 세션 IDCA 공개 인증서server hello 메시지와 함께 담아 응답한다. 이 CA 인증서에는 앞으로 통신 이후 사용할 대칭키가 생성되기 전, 클라이언트에서 handshake 과정 속 암호화에 사용할 공개키를 담고 있다.

  3. 클라이언트 측은 서버에서 보낸 CA 인증서에 대해 유효한 지 CA 목록에서 확인하는 과정을 진행한다.

  4. CA 인증서에 대한 신뢰성이 확보되었다면, 클라이언트는 난수 바이트를 생성하여 서버의 공개키로 암호화한다. 이 난수 바이트는 대칭키를 정하는데 사용이 되고, 앞으로 서로 메시지를 통신할 때 암호화하는데 사용된다.

  5. 만약 2번 단계에서 서버가 클라이언트 인증서를 함께 요구했다면, 클라이언트의 인증서와 클라이언트의 개인키로 암호화된 임의의 바이트 문자열을 함께 보내준다.

  6. 서버는 클라이언트의 인증서를 확인 후, 난수 바이트를 자신의 개인키로 복호화 후 대칭 마스터 키 생성에 활용한다.

  7. 클라이언트는 handshake 과정이 완료되었다는 finished 메시지를 서버에 보내면서, 지금까지 보낸 교환 내역들을 해싱 후 그 값을 대칭키로 암호화하여 같이 담아 보내준다.

  8. 서버도 동일하게 교환 내용들을 해싱한 뒤 클라이언트에서 보내준 값과 일치하는 지 확인한다. 일치하면 서버도 마찬가지로 finished 메시지를 이번에 만든 대칭키로 암호화하여 보낸다.

  9. 클라이언트는 해당 메시지를 대칭키로 복호화하여 서로 통신이 가능한 신뢰받은 사용자란 걸 인지하고, 앞으로 클라이언트와 서버는 해당 대칭키로 데이터를 주고받을 수 있게 된다.

REST & RESTful이란?

REST란 Representational State Transfer의 약자로 웹의 장점을 최대한 활용할 수 있는 Client와 Server 간 통신 방식 중 하나이다.

설계 기본 규칙으로 HTTP URI를 통해 자원을 명시하고 HTTP method(GET, POST, PUT, DELETE)를 통해 자원을 처리하도록 설계된 아키텍처이다.

RESTful은 REST라는 아키텍처를 구현하는 웹 서비스를 나타내는 것으로 REST 원리를 따르는 시스템을 RESTful이라는 용어로 지칭한다.

HTTP는 비상태성(Stateless) 프로토콜로 상태 정보를 유지하지 않는다. 연결을 유지하지 않기 때문에 리소스 낭비가 줄어드는 것은 큰 장점이지만 통신할 때마다 매번 연결 설정을 해야 하며, 이전 요청과 현재 요청이 같은 사용자의 요청인지 알 수 없다는 단점이 존재한다.

쿠키와 세션을 통해서 HTTP의 Stateless한 문제점을 해결할 수 있다.

[저장 위치]

  • 쿠키 : 클라인어트의 웹 브라우저가 지정하는 메모리 or 하드 디스크

  • 세션 : 서버의 메모리

[만료 시점]

  • 쿠키 : 저장할 때, expires 속성을 정의하여 무효화시키면 삭제될 날짜를 지정할 수 있다.

  • 세션 : 클라이언트가 로그아웃하거나 설정 시간 동안 반응이 없으면 무효화되기 때문에 정확한 시점을 알 수 없다.

[리소스]

  • 쿠키 : 클라이언트에 저장되고 클라이언트의 메모리를 사용하기 때문에 서버 자원을 사용하지 않는다.

  • 세션 : 서버에 저장되고, 서버 메모리로 로딩되기 때문에 세션이 생길 때마다 리소스를 차지한다.

[용량 제한]

  • 쿠키 : 클라이언트도 모르게 접속되는 사이트에 의하여 설정될 수 있기 때문에 쿠키로 인해 문제가 발생하는 걸 막고자 한 도메인당 20개, 하나의 쿠키당 4KB로 제한해 두었다.

  • 세션 : 클라이언트가 접속하면 서버에 의해 생성되므로 개수나 용량 제한이 없다.

[보안]

  • 쿠키 : 클라이언트에 저장하기 때문에 보안에 취약하다.

  • 세션 : 서버에 저장하기 때문에 쿠키에 비해서는 보안에 우수하다.

면접 질문에서도 종종 나오는 방식이다. 이해하기 전에 IP 주소와 도메인에 대한 사전 지식이 필요하다.

IP 주소

  • IP 주소란 많은 컴퓨터들이 인터넷 상에서 서로를 인식하기 위해 지정받은 식별용 번호라고 생각하면 된다.

  • 현재는 IPv4 버전(32비트)로 구성되어 있으며, 한번씩은 들어봤을 법한 127.0.0.1 같은 주소를 말한다.

  • 시간이 갈수록 IPv4 주소의 부족으로 IPv6가 생겼는데, 128비트로 구성되어 있기 때문에 IP 주소가 부족하지 않다는 특징이 있다.

도메인 네임(Domain Name)

  • IP 주소는 12자리의 숫자로 되어 있기 때문에 사람이 외우기 힘들다는 단점이 있다.

  • 그렇기 때문에 12자리의 IP 주소를 문자로 표현한 주소를 도메인 네임이라고 한다.

  • 다시 말해서, 도메인 네임은 'naver.com'처럼 몇 개의 의미있는 문자들과 .의 조합으로 구성된다.

  • 도메인 네임은 사람의 편의성을 위해 만든 주소이므로 실제로는 컴퓨터가 이해할 수 있는 IP 주소로 변환하는 작업이 필요하다.

  • 이때, 사용할 수 있도록 미리 도메인 네임과 함께 해당하는 IP 주소값을 한 쌍으로 저장하고 있는 데이터베이스를 DNS(Domain Name System) 이라고 부른다.

  • 도메인 네임으로 입력하면 DNS를 이용해 컴퓨터는 IP 주소를 받아 찾아갈 수 있다.

작동 방식

https://camo.githubusercontent.com/1d907c5b70e225e976ae41bb729c65e4c7e047a550aea90cd7fc7576aff72f32/68747470733a2f2f74312e6461756d63646e2e6e65742f6366696c652f746973746f72792f393946303939333735433132344232443032

  1. 사용자가 브라우저에 도메인 네임([www.naver.com)을](http://www.naver.㯘%29-8040a/) 입력한다.

  2. 사용자가 입력한 URL 주소 중에서 도메인 네임(Domain Name) 부분을 DNS 서버에서 검색하고, DNS 서버에서 해당 도메인 네임에 해당하는 IP 주소를 찾아 사용자가 입력한 URL 정보와 함께 전달한다.

  3. 페이지 URL 정보와 전달받은 IP 주소는 HTTP 프로토콜을 사용하여 HTTP 요청 메시지를 생성하고, 이렇게 생성된 HTTP 요청 메시지는 TCP 프로토콜을 사용하여 인터넷을 거쳐 해당 IP 주소의 컴퓨터로 전송된다.

  4. 이렇게 도착한 HTTP 요청 메시지는 HTTP 프로토콜을 사용하여 웹 페이지 URL 정보로 변환되어 웹 페이지 URL 정보에 해당하는 데이터를 검색한다.

  5. 검색된 웹 페이지 데이터는 또 다시 HTTP 프로토콜을 사용하여 HTTP 응답 메시지를 생성하고 TCP 프로토콜을 사용하여 인터넷을 거쳐 원래 컴퓨터로 전송된다.

  6. 도착한 HTTP 응답 메시지는 HTTP 프로토콜을 사용하여 웹 페이지 데이터로 변환되어 웹 브라우저에 의해 출력되어 사용자가 볼 수 있게 된다.

이렇게 말하면 어느 정도 설명할 수 있지만, 뭔가 부족하다. 조금 더 알아보자.

DHCP & ARP

대부분의 가정집에서는 DHCP로 인터넷 접속을 하고 있다. DHCP는 Dynamic Host Configuration Protocol의 약자로, 호스트의 IP 주소 및 TCP / IP 설정을 클라이언트에 자동으로 제공하는 프로토콜이다. 사용자의 PC는 DHCP 서버에서 사용자 자신의 IP 주소, 가장 가까운 라우터의 IP 주소, 가장 가까운 DNS 서버의 IP 주소를 받는다. 이후, ARP 프로토콜을 이용하여 IP 주소를 기반으로 가장 가까운 라우터의 MAC 주소를 알아낸다.

https://camo.githubusercontent.com/a73920d2cb4265753f0c557225fb233d1710818c60502355a0e0ba92446af6da/68747470733a2f2f74312e6461756d63646e2e6e65742f6366696c652f746973746f72792f323637424343343035383730393134393230

DHCP 서버의 동작 개념도 - 클라이언트가 인터넷 접속을 시도하면 IP와 기본 정보를 제공해준다.

IP 정보 수신

위의 과정을 통해 외부와 통신할 준비를 마쳤으므로, DNS Query를 DNS 서버에 전송한다. DNS 서버는 이에 대한 결과로 웹 서버의 IP 주소를 사용자 PC에 돌려준다. DNS 서버가 도메인에 대한 IP 주소를 송신하는 과정은 약간 복잡하다.

과정 (www.naver.com 이라고 가정하자.)

사용자의 PC는 가장 먼저 지정된 DNS 서버(우리나라의 경우, 통신사별로 지정된 DNS 서버가 있다.)에 DNS Query를 송신한다. 그 후 지정된 DNS 서버는 Root 네임서버www.naver.com을 질의하고, Root 네임서버는 .com 네임서버의 ip 주소를 알려준다.

그 후 .com 네임서버www.naver.com을 질의하면 naver.com 네임서버의 ip 주소를 받고 그곳에 질의를 또 송신하면 www.naver.com의 IP 주소를 수신하게 된다.

이와 같이 여러번 왔다갔다 하는 이유는, 도메인의 계층화 구조에 따라 DNS 서버도 계층화 되어있기 때문이다. 이렇게 계층화되어 있으므로 도메인의 가장 최상단, 즉 가장 뒷쪽(.com, .kr 등등)을 담당하는 DNS 서버는 전세계에 13개 뿐이다.

웹 서버 접속

이제 웹 서버의 IP 주소까지 알았다. Http Request를 위헤 TCP Socket을 개방하고 연결한다. 이 과정에서 3-way hand shaking 과정이 일어난다. TCP 연결에 성공하면, Http Request가 TCP Socket을 통해 보내진다. 이에 대한 응답으로 웹 페이지의 정보가 사용자의 PC로 들어온다.

로드 밸런싱

둘 이상의 CPU or 저장 장치와 같은 컴퓨터 자원들에게 작업을 나누는 것

요즘 시대에는 웹사이트에 접속하는 인원이 급격하게 늘어나게 되었다.

따라서 이 사람들에 대해 모든 트래픽을 감당하기엔 1대의 서버로는 부족하다.

대응 방안으로 하드웨어의 성능을 올리거나(Scale-up) 여러대의 서버가 나눠서 일하도록 만드는 것(Scale-out)이 있다.

하드웨어 향상 비용이 더욱 비싸기도 하고, 서버가 여러 대 존재하면 무중단 서비스를 제공하는 환경 구성이 용이하므로 Scale-out이 효과적이다.

이때, 여러 서버에게 균등하게 트래픽을 분산시켜주는 것이 바로 로드 밸런싱이다.

Scale-up : Server가 더 빠르게 동작하기 위해 하드웨어의 성능을 올리는 방법.

Scale-out : 하나의 Server보다는 여러 대의 Server가 나눠서 일을 하는 방법.

로드 밸런서가 서버를 선택하는 방식

  • 라운드 로빈 : CPU 스케줄링의 라운드 로빈 방식 활용

  • Least Connections : 연결 갯수가 가장 적은 서버 선택(트래픽으로 인해 세션이 길어지는 경우 권장)

  • Source : 사용자 IP를 해싱하여 분배(특정 사용자가 항상 같은 서버로 연결되는 것을 보장)

로드 밸런서 장애 대비

서버를 분배하는 로드 밸런서에 문제가 생길 수 있기 때문에 로드 밸런서를 이중화하여 대비한다.

  • Active 상태

  • Passive 상태

Stateful vs Stateless 서비스와 HTTP 및 REST

reference

HTTP 동작 과정과 HTTP Method, 상태코드

HyperText Transfer Protocal의 약자로써 인터넷 통신을 위해 사용되는 프로토콜이다.

✨ HTTP 동작

Client가 브라우저를 통해 URI을 통해 특정 요청(Request)을 보내면, Server는 해당 요청(Request)을 받아 처리를 하여 Client에게 응답(Response)을 하는 형태

https://user-images.githubusercontent.com/37958836/119261737-ab57f180-bc13-11eb-85d4-cae4e392c5a3.png

✨ HTTP 특징

  • TCP/IP을 이용한 응용 프로토콜이다.

  • 연결 상태를 유지하지 않는 비연결성 프로토콜이다.

  • 요청과 응답 방식으로 동작한다.

  • 서버와 클라이언트에 의해 HTTP 메세지가 해석된다.

✨ HTTP Method

✨ HTTP Status Code

정보전송 임시응답 (1xx)

성공 (2xx)

리다이렉션 (3xx)

클라이언트 요청 오류 (4xx)

서버에러 (5xx)

Blocking, Non-blocking & Synchronous, Asynchronous

https://camo.githubusercontent.com/b7b28ae739c50d5ed8a4594f52f24e671aeeae234befd0991e5230561ba303bf/68747470733a2f2f696d67312e6461756d63646e2e6e65742f7468756d622f523132383078302f3f73636f64653d6d746973746f72793226666e616d653d6874747073253341253246253246626c6f672e6b616b616f63646e2e6e6574253246646e25324664613530597a2532466274713044736a65345a562532466c47653848386e5a676442646746766f3749637a5330253246696d672e706e67

homoefficio님 블로그에 나온 2대2 매트릭스로 잘 정리된 사진이다. 이 사진만 보고 모두 이해가 된다면, 차이점에 대해 잘 알고 있는 것이다.

✨ Blocking/Non-blocking

블럭/논블럭은 간단히 말해서 호출된 함수호출한 함수에게 제어권을 건네주는 유무의 차이라고 볼 수 있다.

함수 A, B가 있고, A 안에서 B를 호출했다고 가정해보자. 이때 호출한 함수는 A고, 호출된 함수는 B가 된다. 현재 B가 호출되면서 B는 자신의 일을 진행해야 한다. (제어권이 B에게 주어진 상황)

  • Blocking : 함수 B는 내 할 일을 다 마칠 때까지 제어권을 가지고 있는다. A는 B가 다 마칠 때까지 기다려야 한다.

  • Non-blocking : 함수 B는 할 일을 마치지 않았어도 A에게 제어권을 바로 넘겨준다. A는 B를 기다리면서도 다른 일을 진행할 수 있다.

즉, 호출된 함수에서 일을 시작할 때 바로 제어권을 리턴해주느냐, 할 일을 마치고 리턴해주느냐에 따라 블럭과 논블럭으로 나누어진다고 볼 수 있다.

✨ Synchronous/Asynchronous

동기/비동기는 일을 수행 중인 동시성에 주목하자

아까처럼 함수 A와 B라고 똑같이 생각했을 때, B의 수행 결과나 종료 상태를 A가 신경쓰고 있는 유무의 차이라고 생각하면 된다.

  • Synchronous : 함수 A는 함수 B가 일을 하는 중에 기다리면서, 현재 상태가 어떤지 계속 체크한다.

  • Asynchronous : 함수 B의 수행 상태를 B 혼자 직접 신경쓰면서 처리한다. (Callback)

즉, 호출된 함수(B)를 호출한 함수(A)가 신경쓰는지, 호출된 함수(B) 스스로 신경쓰는지를 동기/비동기라고 생각하면 된다.

비동기는 호출시 Callback을 전달하여 작업의 완료 여부를 호출한 함수에게 답하게 된다. (Callback이 오기 전까지 호출한 함수는 신경쓰지 않고 다른 일을 할 수 있음)

위 그림처럼 총 4가지의 경우가 나올 수 있다. 이걸 좀 더 이해하기 쉽게 Case 별로 예시를 통해 보면서 이해하고 넘어가보자

상황 : 치킨집에 직접 치킨을 사러감

1) Blocking & Synchronous

나 : 사장님 치킨 한마리만 포장해주세요 사장님 : 네 금방되니까 잠시만요! 나 : 넹 -- 사장님 치킨 튀기는 중-- 나 : (아 언제 되지?..궁금한데 그냥 멀뚱히 서서 치킨 튀기는거 보면서 기다림)

2) Blocking & Asynchronous

나 : 사장님 치킨 한마리만 포장해주세요 사장님 : 네 금방되니까 잠시만요! 나 : 앗 넹 -- 사장님 치킨 튀기는 중-- 나 : (언제 되는지 안 궁금함, 잠시만이래서 다 될때까지 서서 붙잡힌 상황)

3) Non-blocking & Synchronous

나 : 사장님 치킨 한마리만 포장해주세요 사장님 : 네~ 주문 밀려서 시간 좀 걸리니까 볼일 보시다 오세요 나 : 넹 -- 사장님 치킨 튀기는 중-- (5분뒤) 나 : 제꺼 나왔나요? 사장님 : 아직이요 (10분뒤) 나 : 제꺼 나왔나요? 사장님 : 아직이요ㅠ (15분뒤) 나 : 제꺼 나왔나요? 사장님 : 아직이요ㅠㅠ

4) Non-blocking & Asynchronous

나 : 사장님 치킨 한마리만 포장해주세요 사장님 : 네~ 주문 밀려서 시간 좀 걸리니까 볼일 보시다 오세요 나 : 넹 -- 사장님 치킨 튀기는 중-- 나 : (앉아서 다른 일 하는 중) ... 사장님 : 치킨 나왔습니다 나 : 잘먹겠습니다~

Blocking & Non-Blocking I/O

I/O 작업은 Kernel level에서만 수행할 수 있다. 따라서, Process, Thread는 커널에게 I/O를 요청해야 한다.

  1. Blocking I/O

    I/O Blocking 형태의 작업은

    (1) Process(Thread)가 Kernel에게 I/O를 요청하는 함수를 호출

    (2) Kernel이 작업을 완료하면 작업 결과를 반환 받음.

    • 특징

      • I/O 작업이 진행되는 동안 user Process(Thread) 는 자신의 작업을 중단한 채 대기

      • Resource 낭비가 심함(I/O 작업이 CPU 자원을 거의 쓰지 않으므로)

    여러 Client 가 접속하는 서버를 Blocking 방식으로 구현하는 경우 -> I/O 작업을 진행하는 작업을 중지 -> 다른 Client가 진행중인 작업을 중지하면 안되므로, client 별로 별도의 Thread를 생성해야 함 -> 접속자 수가 매우 많아짐

    이로 인해, 많아진 Threads 로 컨텍스트 스위칭 횟수가 증가함,,, 비효율적인 동작 방식

  2. Non-Blocking I/O

    I/O 작업이 진행되는 동안 User Process의 작업을 중단하지 않음.

    • 진행 순서

      1. User Process가 recvfrom 함수 호출 (커널에게 해당 Socket으로부터 data를 받고 싶다고 요청함)

      2. Kernel은 이 요청에 대해서, 곧바로 recvBuffer를 채워서 보내지 못하므로, "EWOULDBLOCK"을 return함.

      3. Blocking 방식과 달리, User Process는 다른 작업을 진행할 수 있음.

      4. recvBuffer에 user가 받을 수 있는 데이터가 있는 경우, Buffer로부터 데이터를 복사하여 받아옴.

        이때, recvBuffer는 Kernel이 가지고 있는 메모리에 적재되어 있으므로, Memory간 복사로 인해, I/O보다 훨씬 빠른 속도로 data를 받아올 수 있음.

      5. recvfrom 함수는 빠른 속도로 data를 복사한 후, 복사한 data의 길이와 함께 반환함.

DNS round robin

✨ DNS Round Robin 방식의 문제점

  1. 서버의 수 만큼 공인 IP 주소가 필요함 부하 분산을 위해 서버의 대수를 늘리기 위해서는 그 만큼의 공인 IP 가 필요하다.

  2. 균등하게 분산되지 않음 모바일 사이트 등에서 문제가 될 수 있는데, 스마트폰의 접속은 캐리어 게이트웨이 라고 하는 프록시 서버를 경유 한다. 프록시 서버에서는 이름변환 결과가 일정 시간 동안 캐싱되므로 같은 프록시 서버를 경유 하는 접속은 항상 같은 서버로 접속된다. 또한 PC 용 웹 브라우저도 DNS 질의 결과를 캐싱하기 때문에 균등하게 부하분산 되지 않는다. DNS 레코드의 TTL 값을 짧게 설정함으로써 어느 정도 해소가 되지만, TTL 에 따라 캐시를 해제하는 것은 아니므로 반드시 주의가 필요하다.

  3. 서버가 다운되도 확인 불가 DNS 서버는 웹 서버의 부하나 접속 수 등의 상황에 따라 질의결과를 제어할 수 없다. 웹 서버의 부하가 높아서 응답이 느려지거나 접속수가 꽉 차서 접속을 처리할 수 없는 상황인 지를 전혀 감지할 수가 없기 때문에 어떤 원인으로 다운되더라도 이를 검출하지 못하고 유저들에게 제공한다. 이때문에 유저들은 간혹 다운된 서버로 연결이 되기도 한다. DNS 라운드 로빈은 어디까지나 부하분산 을 위한 방법이지 다중화 방법은 아니므로 다른 S/W 와 조합해서 관리할 필요가 있다.

Round Robin 방식을 기반으로 단점을 해소하는 DNS 스케줄링 알고리즘이 존재한다. (일부만 소개)

Weighted round robin (WRR)

각각의 웹 서버에 가중치를 가미해서 분산 비율을 변경한다. 물론 가중치가 큰 서버일수록 빈번하게 선택되므로 처리능력이 높은 서버는 가중치를 높게 설정하는 것이 좋다.

Least connection

접속 클라이언트 수가 가장 적은 서버를 선택한다. 로드밸런서에서 실시간으로 connection 수를 관리하거나 각 서버에서 주기적으로 알려주는 것이 필요하다.

Connection Management

Last updated