마이크로서비스 아키텍처 구축 : 4장 마이크로서비스 통신 방식

일단 해볼게·2025년 10월 26일
0

book

목록 보기
32/34

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

  • 네트워크를 통한 두 프로세스 사이의 호출은 한 프로세스 내부의 호출과 다르다.
    • 성능
      • 오버헤드가 크다.
        • 기본 컴파일러, 런타임 호출 최적화 불가능
        • 패킷 전송 필요
        • 프로세스 내부에서 적합한 API가 프로세스 간 상황에서는 적합하지 않을 수 있다.
        • 네트워크를 통해 전송될 수 있는 특정 형태로 직렬화, 역직렬화
          • 전송되는 페이로드 크기 주의
            • 송수신 데이터 양 고려
    • 인터페이스 변경
      • 마이크로서비스 간 통신에서 인터페이스가 바뀌면 문제가 복잡해진다.
        • 각 마이크로서비스는 독립적으로 배포되므로 한쪽의 변경이 다른 쪽의 하위 호환성을 깨뜨릴 수 있다.
        • 해결 방법
          • 락스텝 배포(lockstep deployment) : 생산자와 소비자 서비스를 동시에 업데이트
          • 새 인터페이스를 점진적으로 도입
    • 에러 처리
      • 통제할 수 없는 많은 에러에 취약
        • 네트워크 시간 초과
        • 다운스트림 마이크로서비스가 일시적으로 사용하지 못하는 현상
        • 네트워크 연결이 끊김
      • 프로세스 간 통신에 나타나는 다섯 가지 유형
        • 충돌 실패
          • 갑작스러운 서버 중단
        • 누락 실패
          • 전송 후 응답을 받지 못했다.
        • 타이밍 실패
          • 제 시간에 받지 못했다.
        • 응답 실패
          • 잘못된 응답 수신
        • 임의 실패
          • 무언가 잘못됐지만 참여자들이 실패가 발생한 사실에 동의하지 못하는 경우
      • 에러 의미
        • 503 (Service Unavailable)
          • 일시적 오류 → 재시도 가능
        • 501 (Not Implemented)
          • 재시도가 도움되지 않음
        • 에러 의미 체계를 갖추면 클라이언트가 보상 작업을 수행하기 더 쉬워진다.

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

  • 어떤 기술을 골라야할지 모르겠다면 원하는 통신 방식을 이야기하고 해당 방식을 구현하는 데 적합한 기술을 찾는 것이 중요하다.

4.3 마이크로서비스 통신 방식

  • 통신 방식
    • 동기식 블로킹
      • 다른 마이크로서비스를 호출하고 응답을 기다린다.
    • 비동기식 논블로킹
      • 호출을 보낸 마이크로서비스는 호출 수신 여부에 관계없이 처리를 계속할 수 있다.
    • 요청 및 응답
      • 다른 마이크로서비스에 요청을 보내면 응답을 받을 것을 기대
    • 이벤트 기반
      • 다른 마이크로서비스가 소비하고 반응하는 이벤트 발산
      • 발행하는 이벤트를 어떤 마이크로서비스가 소비하는지 알지 못한다.
    • 공통 데이터
      • 일부 공유 데이터 소스를 통해 협업
  • 모델 적용 시 팀이 운영하는 곳의 문맥을 먼저 파악
    • 신뢰할 수 있는 통신, 허용 가능한 지연 시간, 통신량, 보안 관련 측면 등
  • 짜맞추기
    • 마이크로서비스 전체에 다양한 협업 스타일이 혼재될 수 있다.

4.4 동기식 블로킹

  • 마이크로서비스가 일종의 호출을 다운스트림 프로세스에 보내고 호출이 완료돼 응답이 수신될 때까지 대기한다.
    • 호출 결과가 이후 연산에 필요
    • 장점
      • 간단하다.
    • 단점
      • 시간적 결합
        • 업스트림 인스턴스가 종료되고 다운스트림 인스턴스가 응답을 보낸다면 유실된다.
          • read timeout 시간 설정의 중요성
          • 해결 방법
            • 멱등키를 추가해 재시도 시 도달했는지 유실됐는지 파악
              • 같은 키로 다시 요청이 오면 이미 처리 완료된 요청이면 이전 응답을 재사용(return cached response)
              • 처음 보는 키면 정상 처리 후 결과 저장
      • 다운스트림 프로세스가 네트워크 지연 이슈가 있다면 오랜 시간 동안 블로킹
    • 적용 대상
      • 간단한 마이크로서비스 아키텍처
  • 호출 체인이 많아질 때 문제가 되기 시작
    • 하나라도 문제가 발생하면 전체 작업이 실패할 수 있다.
      • 사용 가능한 커넥션 부족
    • 해결 방법
      • 호출 체인의 길이를 줄인다.
        • 백그라운드에서 병렬 실행
      • 블로킹을 논블로킹으로 변경

4.5 비동기식 논블로킹

  • 응답을 기다릴 필요 없이 다른 처리 가능
  • 세 가지 방식
    • 공통 데이터를 통한 통신
      • 상류 서비스는 일부 공통 데이터를 변경하고 이는 나중에 다른 서비스에서 사용한다.
    • 요청 및 응답
      • 서비스는 다른 서비스에 작업 요청을 보낸다. 작업이 완료되면 성공 여부와 관계없이 상류 서비스는 응답을 수신한다.
      • 상류 서비스의 어떤 인스턴스라도 응답을 처리할 수 있어야 한다.
    • 이벤트 기반 상호작용
      • 이벤트를 발행 및 수신 대응한다.
  • 장점
    • 시간적 결합 회피
  • 단점
    • 복잡도 증가
  • 적용 대상
    • 재구성하기 쉽지 않은 긴 호출 체인이 있는 상황

4.6 공통 데이터를 통한 통신

  • 하나의 마이크로서비스가 데이터를 정의한 위치에 넣고 다른 마이크로서비스가 그 데이터를 이용한다.
    • 비동기식
  • 구현
    • 데이터 영구 저장소에 데이터 저장
      - 폴링 방식으로 파일 변경 여부 확인
      - 데이터 레이크
      - 원시 데이터 업로드
      - 다운스트림 소비자는 이 정보를 처리하는 방법을 알고 있어야 한다.
      - 데이터 웨어하우스
      - 구조화된 데이터 저장소
      - 구조가 하위 호환이 불가능한 방식으로 변경되면 생산자가 업데이트

  • 장점
    • 알려진 기술을 사용해 간단하게 구현
    • 한 번에 많은 데이터 전송에 효과적
  • 단점
    • 다운스트림의 소비자가 폴링 메커니즘이나 주기적으로 트리거되는 정기 작업을 통해 처리할 신규 데이터가 있음을 인식
      • 대기 시간이 짧은 상황에서는 유용하지 못하다.
        • 공유 파일 시스템의 파일 변경 시 다운스트림에 알림을 주는 방식으로 대처
        • 그러나 실시간성이 필요하다면 카프카와 같은 스트리밍 기술이 더 적합
  • 적용 대상
    • 사용 가능한 기술에 제약이 있는 프로세스 사이에서 상호 운용성을 활성화할 때
      • 소비자가 지원 가능한 기술에 제한이 있는 경우
    • 대용량 데이터 공유

4.7 요청 및 응답 통신

  • 마이크로서비스는 다운스트림 서비스에 작업 요청을 보내고 결과를 받길 기대

    • 블로킹, 논블로킹 둘 다 가능
  • 특정 순서로 호출을 완료해야하는 상황에서 일반적

  • 구현: 동기 대 비동기

    • 동기식 블로킹
      • 커넥션을 이용해 데이터 주고 받음
    • 비동기식 논블로킹
    • 메시지 브로커를 통해 메시지 전송
    • 큐 사용 장점
      • 여러 요청 버퍼링 가능
        • 너무 많은 요청이 들어올 때
    • 어려운 점
      • 응답이 요청을 보낸 동일 마이크로서비스의 인스턴스로 되돌아오지 않을 수 있다.
      • 해결 방법
        • 요청과 관련된 모든 상태를 DB에 저장
    • 절대 발생하지 않을 일을 기다리면서 블로킹이 되는 문제를 피하기 위해 타임아웃 처리 필요
    • 병렬 호출로 응답 시간 개선
  • 적용 대상

    • 추가 처리가 일어나기 전에 요청 결과를 확인해야 하는 모든 상황
    • 호출이 되지 않을 때 재시도와 같은 보상 조치를 수행 가능한 마이크로서비스 환경

4.8 이벤트 기반 통신

  • 마이크로서비스가 다른 마이크로서비스에 수신 여부가 보장되지 않는 이벤트 발행
    • 비동기
      • 이벤트 리스너가 자체 실행 스레드에서 실행되기 때문
  • 필요할 때 이벤트를 발행하면 그 책임을 다한 것이다.

  • 느슨한 결합

  • 이벤트 발행자는 무엇을 할지 결정하는 것을 수신자에게 맡긴다.

    • 요청 및 응답 방식에서는 다운스트림 수신자에 대한 도메인을 알고 있어야 하지만, 이벤트 발행자는 다운스트림 수신자가 무엇을 할 것인지 알 필요가 없다.
  • 구현

    • 마이크로서비스가 이벤트를 발행하는 방법
      • API를 이용해 이벤트 발행
    • 소비자가 해당 이벤트 발생을 알아내는 방법
      • 구독을 처리해 소비자가 알림을 받을 수 있게 한다.
  • 이벤트에 포함되는 것

    • 예시

      • 누가 이벤트를 받는지 알 수 없고 알아서도 안 되는 상황에서 필요한 정보

      • 고객의 식별자만

        • 통지 마이크로서비스는 고객의 이메일을 알아야하므로 고객 마이크로서비스에서 정보를 가져온다.

      • 매우 자세한 이벤트

        • API를 통해 공유하는 모든 것을 이벤트에 삽입

        • 장점

          • 고객 마이크로서비스를 호출하지 않으므로 느슨한 결합
        • 단점

          • 이벤트 크기 증가
      • 이벤트 크기에 따라 방식 선택 권장

    • 민감 데이터를 볼 수 있는 마이크로서비스 범위를 제한한다면?

      • 두 가지 유형의 이벤트를 보낸다.
        1. PII(개인을 식별할 수 있는 정보)를 포함한 이벤트
        2. PII를 제외한 이벤트
          1. 광범위한 브로드캐스트
      • 이벤트가 늘어나 복잡성 증가
  • 적용 대상

    • 정보를 브로드캐스트하길 원하는 상황과 의도를 뒤집는 상황에서 효과적
    • 느슨한 결합에 중점을 두는 상황
  • 요청 및 응답 상호작용을 이벤트 기반의 상호작용으로 바꾸는 팀이 역방향보다 더 많다.

4.9 조심해서 진행하라

  • 복잡성에 대해 고려
    • 요청을 시작한 동일 노드로 되돌아온다했을 때 노드가 다운된다면?
      • 대응할 수 있는 정보를 어디에 저장할까?
  • 파국적 페일오버
    • 워커가 특정 예외로 인해 죽고나서 다시 큐로 인입되어 다른 워커도 죽어나가는 경우
  • 모니터링 필요
    • 프로세스 경계를 거쳐 요청을 추적하게 해주는 ID 사용 적극 고려
profile
시도하고 More Do하는 백엔드 개발자입니다.

0개의 댓글