마이크로서비스 통신 방식

  • 이장에서는 마이크로서비스간 통신 방식을 소개, 분석
  • 요청 및 응답 방식과 이벤트 기반 협업 방식을 비교
  • 동기식 블로킹, 비동기식 논블로킹

프로세스 내부에서 프로세스 사이로

  • 성능
  • 인터페이스 변경
  • 에러처리
    • 프로세스 간 통신에서 발생가능한 다섯 가지 실패모드(Distributed Systems)
      • 충돌 실패(crash failure)
      • 누락 실패(omission failure)
      • 타이밍 실패(timing failure)
      • 응답 실패(response failure)
      • 임의 실패(arbitary failure)

프로세스 간 통신을 위한 기술: 다양한 선택

  • 프로세스 간 통신에 사용하는 기술의 범위는 방대함
  • 기술 선택시 자신에게 익숙한 기술 또는 컨퍼런스에서 배운 최신 기술에 끌림
    • 그러나 이것은 좋은 생각이 아님
  • 원하는 통신 방식 선택, 해당 방식을 구현하는데 적합한 기술을 찾는 것이 중요

마이크로서비스 통신 방식

  • 용어에 대한 간략한 설명
    • 동기식 블로킹
    • 비통기식 논블로킹
    • 요청 및 응답
    • 이벤트 기반 상호작용
    • 공통 데이터
  • 올바른 방식 결정을 위해 컨텍스트 이해에 많은 시간을 할애
    • 통신의 신뢰성, 허용 가능 지연 시간, 통신량
    • 요청 및 응답 방식? 이벤트 기반 방식?
      • 동기, 비동기 모두 사용가능하다면 이벤트 기반 방식 선택
      • 이벤트 기반 방식은 비동기 논블로킹 방식으로 제한됨
  • 통신 방식 외에도 다음과 같은 고려사항이 존재
    • 지연 시간이 짧은 통신의 필요성
    • 보안 관련 측면
    • 확장 기능 등
  • 다양한 통신 방식이 조합되어서 사용

동기식 블로킹

  • 다운스트림 프로세스를 호출하고 완료(응답)될때까지 대기(즉 블로킹 됨)
    • 대기하는 이유는 호출 결과가 필요하거나 정상 작동 여부 확인 및 재시도 등
    • 필자가 본 사실상 모든 동기식 블로킹 호출은 요청 및 응답 호출로 구성
  • 장점
    • 익숙함
  • 단점
    • 동기식 호출의 주요 문제점은 고유한 시간적 결합
    • 다운스트림 서비스가 동작하지 않으면 업스트림 서비스도 실패
      • 다운스트림 서비스의 응답이 늦으면 업스트림 서비스는 지연 시간만큼 블로킹되어있음
    • 다운스트림 서비스가 응답했는데 업스트림 서비스가 종료됐다면 응답은 손실
    • 양뱡향 결합
    • 동기식 호출은 비동기식 호출에 비해 다운스트림 장애로 인한 연쇄적인 문제에 더 취약함
  • 적용 대상
    • 간단한 마이크로서비스 아키텍처라면 동기식 블로킹 호출을 사용하는데 큰 문제가 없음
    • 필자의 경우, 이러한 호출 유형은 호출 체인이 더 많아질 때 문제가 되기 시작함
      • 리소스 경합을 차치하더라도 서비스중 하나만 실패하거나 네트워크 호출에 문제가 발생하면 전체 작업 실패

비동기식 논블로킹

  • 호출하는 마이크로서비스가 블로킹 되지 않음
  • 마이크로서비스 아키텍처에서 가장 일반적인 세 가지 방식
    • 공통 데이터를 위한 통신
    • 요청 및 응답
    • 이벤트 기반 상호작용
  • 장점
    • 호출을 수행하는 서비스와 호출을 수신하는 서비스는 일시적으로 분리
      • 호출을 수신하는 서비스가 호출과 동시에 연결될 필요는 없음
    • 처리하는데 오랜 시간이 걸리는 경우 유용
      • 호출되는 서비스는 처리 완료후 call back을 통해 처리한 서비스에 응답
  • 단점
    • 동기식 블로킹 통신과 비교하면 비동기 논블로킹 통신의 주요 단점은 복잡도와 선택범위에 존재
      • 비동기 통신방식은 다양함
    • async/await
  • 적용 대상
    • 어떤 유형의 비동기식 통신을 선택할지도 고려해야함
    • 일반적으로 비동기식 통신을 사용해야하는 특정 사용 사례가 존재
      • 장기 수행 프로세스
      • 재시도하기 쉽지 않은 긴 호출 체인이 있는 상황
  • 가장 일반적인 세 가지 비동기 통신 형태인 요청 및 응답 호출, 이벤트 기반 통신, 공통 데이터를 통한 방식을 보면서 더 자세히 살펴봄

공통 데이터를 통한 통신

  • 하나의 서비스가 데이터를 정의한 위치에 저장, 다른 여러 마이크로서비스들이 해당 데이터에 접근
    • [그림]
  • 구현
    • 데이터에 대한 영구 저장소가 필요
    • 데이터에 접근하는 모든 다운스트림 서비스들은 데이터가 가용하다는 사실을 확인하는 메커니즘이 필요
      • 폴링 등
    • 이 패턴의 두가지 예
      • 데이터 레이크(data lake)
      • 웨어하우스(data warehouse)
  • 장점
    • 일반적으로 알려진 기술을 사용해 매우 간단하게 구현 가능
      • 파일
      • 데이터베이스
    • 한번에 많은 데이터를 전송한다면 효과적
  • 단점
  • 적용 대상
    • 이 패턴이 빛을 발하는 순간은 사용 가능한 기술에 제약이 있는 프로세스 사이에서 상호 운용성을 활성화 할 때

요청 및 응답 통신

  • 요청 및 응답을 사용하면 동기식 블로킹 또는 비동기식 논블로킹 방식으로 구현가능함
  • 구현: 동기 대 비동기
    • 동기식
      • 업스크팀 서비스와 다운스트림 서비스간의 커넥션이 생성
      • 업스트림 서비스가 응답할때까지 다운스트림 서비스는 대기
      • 둘중 하나가 종료돼 커넥션이 끊어지면 문제가 발생할 수 있음
    • 비동기식
      • 메시지 브로커를 통해 메시지를 전송
      • 업스크림 서비스의 응답을 받아서 처리해야하는 상황에서는 요청과 관련된 모든상태를 데이터베이스에 저장하고 응답이 올 때 수신한 인스턴스가 관련된 상태를 다시 로드해서 적절히 동작할 수 있도록 함
      • 타임아웃 처리 필요
  • 적용 대상
    • 추가 처리가 일어나기 전에 요청 결과를 처리해야 하는 모든 상황에 적합
    • retry가 필요한 환경에서 매우 적합

이벤트 기반 통신

  • 마이크로서비스가 다른 마이크로서비스에 작업을 요청하는 대신 수신 여부가 보장되지 않는 이벤트를 발행
    • 본질적으로 비동기식 동작
  • 이벤트를 발행하는 서비스는 이벤트를 사용하려는 서비스의 존재사실조차 인식하지 못할 수 있음
    • 이벤트를 발행하면 그 책임을 다한것
    • 서비스간 결합도를 크게 줄임
  • 이벤트와 메시지
  • 구현
    • 고려해야할 두가지 측면
      • 마이크로서비스가 이벤트를 발행하는 방법과 알아내는 방법
    • 전통적으로 래빗엠큐 같은 메시지 브로커는 두 문제를 모두 처리하려고함
      • 생산자는 API를 통해 이벤트 브로커에 발행
      • 소비자는 구독을 통해 브로커로부터 알림을 받음
      • 이와 같은 시스템은 일반적으로 확장성과 회복 탄력성을 갖추도록 설계되지만 공짜는 아님
        • 개발 및 테스트 복잡도 증가
        • 추가적인 인프라스트럭처가 필요, 이에 대한 전문지식 필요
      • 메시지 브로커는 미들웨어의 일부에 불과하므로 주의해야함
    • HTTP 기반 이벤트 전파
      • 아톰
      • 경쟁 소비자 패턴
  • 이벤트에 포함되는것
    • 멤버십(Loyalty)과 통지(Notifications)
    • 딱 ID만
    • 매우 자세한 이벤트
  • 적용 대상
    • 느슨한 결합에 더 중점을 두는 상황에 사용
    • 주의할 점은 이러한 방식이 새로운 복잡성의 원인이 되는 경우가 많음
    • 마이크로서비스 아키텍처에서는 다양한 상호작용 방식이 혼합될 수 있다는 사실을 상기

조심해서 진행하라

  • 이벤트 기반 아키텍처는 훨씬 더 분리되고 확장 가능한 시스템이 될것으로 보임
    • 실제로 그럴수 있음
    • 그러나 이러한 통신 방식은 복잡성을 증가시킴

요약

  • 마이크로서비스 통신의 몇 가지 주요 방식을 분석하고 다양한 절충한을 논의함