외부 연동이 문제일 때 살펴봐야 할 것들

  • 마이스로서비스 환경이 도입 되면서 내부든 외부든 서비스간 연동이 보편화 되고 복잡해지고 있음
  • 이때 외부 서비스에서 장애가 발생하면 외부 서비스를 호출하는 내부 서비스에도 장애가 전파될 수 있음
  • 이 장에서는 이런 서비스 연동시 발생할 수 있는 장애를 최소화하는 방법을 살펴봄

타임아웃

  • 2가지의 타입아웃
    • 연결 타임아웃: 3초 ~ 5초
    • 읽기 타임아웃: 5초 ~ 30초

재시도

  • 연동 실패시 다시 시도하는것
  • 재시도 가능 조건
    • 무조건 재시도 가능한건 아님
      • 예를 들어 포인트 차감 등의 API를 재시도하면 중복 차감이 발생할 수 있음
      • 위 2가지 타임아웃중 읽기 타임아웃에 해당
    • 보통 다음 상황시 재시도 가능
      • 단순 조회 기능
      • 연결 타임아웃
      • 멱등성(idempotent)을 가진 변경 기능
  • 재시도 횟수와 간격
    • 재시도시에는 다음 2가지를 결정해야함
      • 재시도 횟수
      • 재시도 간격
    • 무한정 재시도를 할 수는 없음
      • 네트워크 장애 등으로 일시적으로 실패할 수 있음
      • 몇 번의 시도로 위 상황에 대한 대처가능
      • 서버 자체가 문제인경우 계속된 재시도는 무의미
  • 재시도 폭풍(retry storm) 안티패턴
    • 연동된 서버에서 부하로 인한 장애가 발생한 경우 계속된 재시도는 장애를 악화시킬 수 있음
    • 따라서 재시도는 연동 서비스의 성능 상황도 함께 고려해야함

동시 요청 제한

  • 연동 서비스 최대 동시 요청수가 100일때 300개의 요청을 보내면 응답 시간에 문제가 발생, 이는 우리 서비스에도 영향을 미침
    • 특히 선착순 이벤트 등과 같은 트래픽이 몰릴때 발생 가능
  • 벌크헤드(Bulkhead)
    • 동시 요청수를 제한하는 방법
    • 연동서비스가 최대 100개의 요청을 처리할수 있으면 300개의 요청이 들어올때 100개만 보내고 나머지 200개는 실패처리

서킷 브레이커

  • 서킷 브레이커의 상태
    • 닫힘(Closed)
    • 열림(Open)
    • 반 열림(Half-Open)
  • 빠른 실패

외부 연동과 DB연동

  • 외부 연동과 트랜잭션 처리
    • 외부 연동과 DB연동을 함께 처리할때 트랜잭션 처리를 어떻게 할지 고민
    • 외부 연동에 실패했을때 트랜잭션 롤백
      • 외부 연동이 실패해 트랜잭션을 롤백하는 경우 DB 데이터에 이상이 생기는것을 방지할 수 있음
      • 그러나 타임아웃이 발생해서 트랜잭션을 롤백하는 경우, 외부 서비스가 실제로는 성공적으로 처리했을 가능성을 염두해야함
      • 이때는 2가지 방법이 있음
        • 일정 주기로 두 시스템의 데이터가 일치하는지 확인하고 보정
        • 일정 시간후 성공 확인 API를 호출
      • 외부 서비스에서 성공 확인 API를 지원할때만 사용가능
      • 두 시스템간 일관성을 정기적으로 확인하는 프로세스를 갖추는 것이 바람직함
    • 외부 연동은 성공했지만 DB 연동에 실패 트랜잭션을 롤백
      • 외부 연동은 성공했지만 DB 연동에 실패한경우 취소 API를 호출해서 이전 상태로 되돌리는것이 필요
      • 이 경우도 두 시스템간 일관성을 정기적으로 확인하는 프로세스를 갖추는 것이 바람직함
  • 외부 연동이 느려질 때 DB 커넥션 풀 문제
    • 외부 연동이 느려지면 DB 커넥션 풀이 고갈될 수 있음
    • DB 연동과 무관하게 외부 연동을 실행해서 커넥션 풀 포화 상황을 방지 가능
      • 단 외부연동 실패시 트랜잭션 롤백 불가능
      • 이때문에 후처리 고민필요, 보상 트랜잭션 등을 사용하는 방법이 존재

HTTP 커넥션 풀

연동 서비스 이중화

  • 서비스가 성장해서 트래픽이 많아지면 이중화를 고려해야함
  • 2가지를 고려해야함
    • 해당 기능이 서비스의 핵심인지
    • 이중화 비용이 감당 가능한 수준인지