- 이장에서는 마이크로서비스간 통신 방식을 소개, 분석
- 요청 및 응답 방식과 이벤트 기반 협업 방식을 비교
- 동기식 블로킹, 비동기식 논블로킹
프로세스 내부에서 프로세스 사이로
- 성능
- 인터페이스 변경
- 에러처리
- 프로세스 간 통신에서 발생가능한 다섯 가지 실패모드(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만
- 매우 자세한 이벤트
- 적용 대상
- 느슨한 결합에 더 중점을 두는 상황에 사용
- 주의할 점은 이러한 방식이 새로운 복잡성의 원인이 되는 경우가 많음
- 마이크로서비스 아키텍처에서는 다양한 상호작용 방식이 혼합될 수 있다는 사실을 상기
조심해서 진행하라
- 이벤트 기반 아키텍처는 훨씬 더 분리되고 확장 가능한 시스템이 될것으로 보임
- 실제로 그럴수 있음
- 그러나 이러한 통신 방식은 복잡성을 증가시킴
요약
- 마이크로서비스 통신의 몇 가지 주요 방식을 분석하고 다양한 절충한을 논의함