소프트웨어: 가상화의 여행 (1) 통신 방법

H/W, OS, Virtual Machine, Container 부터 Cloud 까지(1)

SoniaComp
11 min readMay 5, 2021

🤔 이 글의 출발점

모든 S/W 는 세단계로 정의할 수 있습니다. Input 값과 Output 값, 그리고 Input 값을 원하는 Output 값으로 만들기 위한 알고리즘으로요!

이런식으로 여러 IT 기술들의 철학, 구성이 하나의 청사진(Blue Print)으로 수렴하는 경우가 많은 것 같습니다. 소프트웨어 시리즈 글은 컴퓨터를 공부하는 분들과 이런 인사이트를 공유하며 함께 생각해보고 싶어 작성했습니다.
(수정이 필요한 부분은 꼭 알려주시면 감사하겠습니다! 😊)

목차

통신방법: 커뮤니케이션/워크플로우 확장 관점에서 중요![물리적인 확장]
- 하나의 컴퓨터
- LAN
- WAN
[프로세스 간 통신]
- IPC : 한 컴퓨터 내
- RPC : 분산 시스템
- REST API : 효율적으로 통신
[느슨한 결합을 위한 통신 방법]
- 강한 결합 시스템의 한계
- 느슨한 결합과 옵저버 패턴
- 비동기 메시징 패턴(브로커리스)
- 비동기 메시징 패턴(브로커 기반)
[클라우드 서비스]
- Azure API Management

물리적인 확장

하나의 컴퓨터

  • 컴퓨터의 세가지 구성요소: CPU(중앙처리장치), Memory(기억장치), I/O 장치(입출력장치)
  • 이 세가지를 이어주는 것: 시스템 버스
  • 시스템버스: 하드웨어 구성 요소를 물리적으로 연결하는 선
  • 데이터 버스: 중앙처리장치와 기타 장치사이에서 데이터를 전달하는 통로(주소버스는 중앙처리장치가 주기억장치나 입출력장치로 기억장치 주소를 전달하는 통로이기 때문에 ‘단방향’ 버스임)
  • 주소 버스: 데이터를 정확히 실어나르기 위해서는 기억장치 ‘주소’를 정해주어야 함(주소버스는 중앙처리장치가 주기억장치나 입출력장치로 기억장치 주소를 전달하는 통로이기 때문에 ‘단방향’ 버스임)
  • 제어 버스: 주소 버스와 데이터 버스는 모든 장치에 공유되기 때문에 이를 제어할 수단이 필요함(제어 버스는 중앙처리장치가 기억장치나 입출력장치에 제어 신호를 전달하는 통로임. 제어 버스는 읽기 동작과 쓰기 동작을 모두 수행하기 때문에 ‘양방향’ 버스임)

네트워크

리소스를 공유하는 방법

  • 네트워크 구성요소: 컴퓨터, 통신 매체, 데이터
  • 컴퓨터를 이어주는 물리적인 장치: 인터페이스, 통신 매체
    (인터페이스: 데이터를 주고받기 위한 규칙을 제어)
    (데이터는 통신매체에 의해 표현방법이 다르다. ex. 케이블 — 전기신호)
  • 컴퓨터를 이어주는 방법
    1) 멀티 액세스 네트워크: 허브, 스위치 [L2, MAC]
    2) 포인트 투 포인트 네트워크: 라우터 [L3]
  • 데이터 통신 방법
    → 회선 교환: 통신 기간 동안 독점적인 사용. 파이프 교체 방식.
    → 패킷 교환: 데이터를 패킷으로 분할해서 송신하기 때문에 회선을 점유하지 않는다. 다수의 컴퓨터가 사용할 경우 유리한 방식

LAN (Local Area Network)

  • 장치들을 연결하는 형식: Topology (Ring형, Bus형, Star형)

WAN (Wide Area Network)

  • AS(Autonomous System, 고유한 AS 번호) 라고 부르는 네트워크들의 집합
  • BGP(Border Gateway Protocol): AS와 AS가 통신할 때 사용하는 프로토콜. 이 프로토콜을 사용해 라우팅함 [EGP]
  • Peering: BGP 를 이용해서 AS 끼리 연결하는 것
  • 전용회선 연결 or 인터넷 VPN 을 사용해 연결
  • ISP(Internet Service Provider) 를 통해 접속

프로세스간 통신

IPC (Inter Process Communication)

다른 프로세스와 통신하는 방법
→ 데이터 공유
→ Concurrency 하게 처리 (Speed up)

  1. PIPE: 데이터 흐름
    → 반이중 통신(단방향)
  2. Message Queue: 메시지 교환을 위한 메모리 공간
    → 직관적이고 간단한 방법
    → 메시지 type에 의해 여러 종류의 메시지를 효과적으로 다룰 수 있다. (ex. 필요로 하는 메시지만을 가져가게 함)
  3. 공유 메모리: 중개자 없이 곧바로 메모리 접근을 통해 공유
    → 커널은 해당 프로세스에 메모리를 할당해주고, 다른 프로세스의 접근을 허용

[ 파이썬에서 메시지큐 ]

  • 메시지큐: 애플리케이션이 서로 메시지를 보내는 분리된 방식으로 통신할 수 있도록 하는 시스템. 큐잉 프로토콜을 통해 통신.
  • Sender Application에서 Receiver Application으로 전달되는 메시지인 ‘데이터 패킷’ 전달
  • 메시지 큐는 Receiver가 메시지를 처리할 수 있을 때까지 메시지를 큐에 저장하는 Store and Forward 의미 체계를 제공
  • AMQP(Advanced Message Queueing Protocol) → RabbitMQ

[ 파이썬에서 분산 태스크큐: Celery ]

  • Celery: 분산 메시지를 사용해 동작하는 파이썬으로 작성된 분산 태스크 큐 (태스크: Celery 안에서 각 실행 단위)
  • Worker라는 프로세스를 사용해 하나 이상의 서버에서 동시에 실행
    [보통 multiprocesssing, gevent같이 다른 백엔드를 사용할수도 있다]
  • 동기적, 비동기적으로 실행 가능
    (샐러리는 메시지 큐와 함께 동작할 수 있다. 샐러리는 큐로부터 메시지를 수락하고 여러 머신으로 태스크를 분배할 수 있다.)
  • 태스크의 결과는 저장소 백엔드에도 저장될 수 있다.
    (샐러리는 브로커 백엔드로 Redis와 함께 동작할 수 있다.)
  • 샐러리는 태스크를 수행하고 여러 서버에 있는 워커로 태스크를 확장하기 때문에 컴퓨터를 사용하는 계산의 확장뿐 아니라 데이터 병렬 처리를 포함하는 문제에도 적합하다.

RPC (Remote Process Communication)

네트워크를 통해 연결된 다른 컴퓨터의 프로세스와 통신하는 방법
클라이언트 프로그램이 원격 서버에서 수행되는 프로그램의 기능을 마치 자신의 Local Procedure를 호출하는 것처럼 사용하게 함

출처: pk.org

REST API

  1. 상태를 가지지 않도록 만든다: 구현이 쉽고, 캐시를 사용할 수 있어 성능이 우수하다
  2. URI는 디렉토리 구조처럼 계층적으로 만든다: URI의 가독성이 좋고 리소스의 구조를 이해하기 쉽다
  3. HTTP 메소드를 명시적으로 사용한다: 리소스의 상태 변화를 HTTP 메소드를 활용하여 리소스 중심으로 처리하고 별도의 메소드를 사용해서 행위 중심으로 처리하지 않도록 한다.
  4. 응답할 때 XML이나 JSON을 사용한다: 데이터 표현을 정규화해서 다른 언어나 기술 구조에서도 데이터를 활용할 수 있도록 한다.

[ 장점 ]

  • 단순하고 익숙

[ 단점 ]

  • 가용성이 떨어집니다. 중간에서 메시지를 버퍼링하는 매개자 없이 클라이언트/서비스가 직접 통신하기 때문에 교환이 일어나는 동안 양쪽 다 실행 중이어야 함
  • 서비스 인스턴스들의 위치를 클라이언트가 알고 있어야 합니다.

[ 부분실패를 처리해 가용성을 높이는 방법 ]

  • 견고한 RPI(Remote Procedure Invocation) 설계
  1. 네트워크 타임아웃: 응답 대기 중에 무한정 블로킹하면 안 되고 타임아웃 설정
  2. 미처리 요청 개수 제한: 클라이언트가 특정 서비스에 요청 가능한 미처리 요청의 최대 개수를 설정. 이 개수에 이르면 더 이상의 요청은 무의미하므로 즉시 실패 처리하는 것이 타당하다.
  3. 회로 차단기 패턴: 성공/실패 요청 개수를 지켜보다가 에러율이 주어진 임계치를 초과하면 그 이후 시도는 바로 실패 처리함. 실패되는 요청이 많다는 것은 서비스가 불능 상태고 더이상의 요청은 무의미하다는 뜻. 타임아웃 시간 이후 클라이언트가 재시도해서 성공하면 회로 차단기는 닫힌다.
  • 무응답 원격 서비스를 어떻게 복구하면 좋을지는 그때그때 상황에 맞게 판단해야 한다.

느슨한 결합을 위한 통신 방법

강한 결합 시스템의 한계

  • 두 시스템이 강하게 결합돼 있으면, 시스템은 서로 특정 한계 이상으로 확장하는 것을 방해한다.
  • 한 컴퓨터 내에도 데이터와 계산이 같은 함수에 함께 있다면, 여러 CPU코어 같은 기존 리소스를 활용하지 못한다.
    → 같은 함수(프로그램)을 멀티 스레드와 이들 사이의 큐 같은 메시지 전달 시스템을 사용하도록 변경하면 프로그램이 여러 CPU로 잘 확장된다.

느슨한 결합

  • 확장성의 중요한 측면 중 하나는 시스템 사이의 결합도를 감소시키는 것
  • 느슨한 결합(Loose Coupling): 둘이 상호작용하지만, 서로에 대해 독립적

느슨한 결합과 옵저버 패턴

  • 느슨한 결합은 옵저버 패턴의 큰 특징 중 하나다.
    (느슨한 결합에 대해 더 확실히 알기 위해 잠깐 옵저버 패턴도 살펴보자!)
  • 옵저버 패턴: 옵저버들(객체의 상태 변화를 관찰하는 관찰자들)의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴
  • 옵저버 패턴의 느슨한 결합의 장점
    → 옵저버를 언제든 새로 추가, 제거할 수 있다.
    → 새로운 형식의 옵저버라 할지라도 Subject를 전혀 변경할 필요가 없다.
    → Subject와 옵저버는 서로 독립적으로 재사용할 수 있다.
    → Subject나 옵저버가 바뀌더라도, 서로에게 영향을 미치지 않는다.

[ 옵저버 패턴과 SOLID 설계 원칙 ]

  • 인터페이스 분리 원칙: class 는 자신이 사용하지않는 interface는 구현하지 말아야 한다. 하나의 일반적인 interface보다 여러개의 구체적인 interface가 낫다.
  • 의존 역전 원칙: 의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존(구체적인 class보다 interface와 관계를 맺는 것)

비동기 메시징 패턴 (브로커리스)

서비스가 직접 통신하는 브로커리스 기반의 메시징 아키텍처
(메시징: 서비스가 메시지를 서로 비동기적으로 주고받는 통신방식)

[ 장점 ]

  • 네트워크 트래픽이 가볍고 지연시간이 짧음 (직접 송수신)
  • 운영 복잡도가 낮음(브로커를 설정/관리할 필요가 없음)

[ 단점 ]

  • 서비스가 서로의 위치를 알고 있어야 함
  • 메시지 교환 시 송수신자 모두 실행중이어야 하므로 가용성이 떨어짐

비동기 메시징 패턴(브로커 기반)

메시지 브로커: 모든 메시지가 지나가는 중간 지점

[ 장점 ]

  • 느슨한 결합: 클라이언트는 서비스 인스턴스를 몰라도 된다. 위치도 몰라도 된다. 그냥 적절한 브로커(채널)에 메시지를 보내는 식으로 요청한다.
  • 메시지 버퍼링: 처리 가능한 시점까지 메시지를 버퍼링한다.
    → HTTP 같은 동기 요청/응답 프로토콜을 쓰면 클라이언트가 수신할때까지 Block 되지만, 메시징을 쓰면 컨슈머가 처리할 수 있을 때까지 그냥 큐에 메시지가 보관된다.
  • 유연한 통신: 다양한 상호작용 스타일을 지원
  • 명시적 IPC

[ 단점 ]

  • 성능 병목 가능성: 메시지 브로커가 성능 병목점이 될 위험이 있다.
  • 단일 장애점 가능성: 메시지 브로커는 가용성이 높아야 한다.
  • 운영 복잡도 부가: 설치/관리해야 할 시스템 컴포넌트이다.

[클라우드 서비스]

클라우드에서는 하나의 가상 스위치에 하나의 서브넷이 할당된다.ㅋz

Azure 에 분산시스템의 API 통신을 관리할 수 있는 유용한 서비스가 있어서 소개한다!

Azure API Management

오늘날의 혁신적인 엔터프라이즈는 API 아키텍처를 채택하여 성장을 가속화합니다. 한 곳에서 모든 API를 관리하여 하이브리드 및 다중 클라우드 환경의 작업을 간소화하세요.

  1. 클라우드 및 온-프레미스 전반에서 API 관리
    → API 게이트웨이를 다른 클라우드 및 온-프레미스에 호스트된 API와 함께 배포하여 API 트래픽 흐름 최적화
    → 보안 및 규정 준수 요구사항을 충족하면서도 내 외부의 모든 API에서 통합 관리 환경과 전체 가시성을 활용
  2. 리소스 보호 지원
    → 인증, 권한 부여 및 사용량 제한을 적용하여 사용자별 선택적 표시
  3. 비즈니스 가속화
    → API 중심 접근 방식을 통해 더 빠르게 앱을 빌드하고 즉각적으로 가치를 고객에게 제공. API 수정 및 버전 지정, API 자동화 설명서에 따라 프런트엔드 및 백엔드 팀을 분리
  4. API 검색 기능 향상
    → 모든 API에 사용할 사용자 지정 가능한 개발자 포털
    → 백엔드 서비스를 REST 기반 API로 전환하는데 도움(기존 서비스 혁신)
  5. API 보안 지원
    → 모든 API를 단일 정적 IP 또는 도메인 아래에 유지하고 키, 토큰 및 IP 필터링을 사용하여 보호하도록 지원
    → 유연하고 세분화된 할당량 및 요금 제한을 적용. 정책을 사용하여 API의 형태와 동작을 수정합니다. 응답 캐싱을 사용하여 대기 시간을 줄이고 API 크기를 조정합니다.

--

--

SoniaComp

Data Engineer interested in Data Infrastructure Powering Fintech Innovation (https://www.linkedin.com/in/sonia-comp/)