[백엔드] 외부 서비스 연동 관련 필수 지식

목차

1. 외부 서비스 연동

1. 타임아웃과 재시도

1) 타임아웃 (Timeout)

  • 연동된 외부 서비스에 대해 타임아웃을 설정하지 않으면, 내 서버의 상태와 상관없이 처리량이 급격히 떨어질 수 있음.
  • 타임아웃 종류:
    • 연결 타임아웃 (Connection Timeout): 외부 서비스와 네트워크 연결을 시도하는 단계에서 기다릴 수 있는 최대 시간. (권장: 3~5초)
    • 읽기 타임아웃 (Read Timeout): 연결된 외부 서비스에 요청을 전송하고 응답을 받을 때 기다릴 수 있는 최대 시간. (권장: 5~30초)
  • 읽기 타임아웃이 긴 이유: 결제 서비스 등에서 응답이 늦게 올 경우, 내 서버에선 타임아웃으로 실패 처리했지만 외부 서비스에선 성공 처리되는 데이터 불일치 문제를 최소화하기 위함임.
  • 주의사항 (소켓 타임아웃): 패킷 하나하나에 대한 응답 시간이므로, 전체 응답 시간과는 다를 수 있음.

2) 재시도 (Retry)

  • 외부 연동 실패 시 재시도 처리를 할 수 있지만, 상황에 따라 주의해서 사용해야 함.
  • 재시도 권장 상황:
    • 단순 조회 기능일 때.
    • 연결 타임아웃이 발생했을 때 (아직 요청이 전달되지 않음).
    • 멱등성(Idempotence)이 보장된 변경 기능일 때.
  • 재시도 금지 상황: 검증 오류(4xx) 등 재시도해도 실패가 확정적인 경우.

2. 재시도 횟수와 간격

  • 연동 서비스가 과부하 상태일 때 무분별한 재시도는 상황을 악화시킴.
  • 재시도 횟수: 1~2번이면 충분함. (총 3번 시도해도 안 되면 일시적 오류가 아닐 확률이 높음)
  • 재시도 간격: 네트워크 단절 등 특정 시간 동안 복구가 안 될 경우를 대비해, 간격을 점차 늘려가며 보내는 방식(Exponential Backoff) 등을 고려해야 함.

2. 동시 요청 제한

1. 동시 요청 제한 (Bulkhead Pattern)

  • 연동 서비스가 처리할 수 있는 용량에 맞춰 내 서버에서 보내는 동시 요청 수를 제한해야 함.
  • 내 서버 트래픽이 300이어도 연동 서비스가 100만 처리가능하다면, 나머지 200은 대기하거나 실패 처리하여 연동 서비스의 장애를 방지해야 함.
  • 이를 통해 특정 기능의 장애가 전체 시스템으로 전파되는 것을 막을 수 있음.

2. 서킷 브레이커 (Circuit Breaker)

  • 연동 서비스가 장애 상태일 때 계속 요청을 보내는 것은 리소스 낭비임.
  • 장애가 감지되면 즉시 에러를 반환하는 빠른 실패(Fail Fast)를 유도하여 시스템 전체의 안정성을 확보함.
  • 일정 시간 후 다시 요청을 보내보고, 정상화되었으면 차단을 해제하는 방식으로 동작함.

3. 외부 연동과 DB처리

1. 트랜잭션 처리

  • 하나의 트랜잭션 내에서 외부 연동과 DB 처리가 섞여 있을 때, 실패 케이스별로 대응 전략이 필요함.
  • 외부 연동 실패 시:
    • 연결 타임아웃: 요청 자체가 안 갔으므로 트랜잭션 롤백하면 됨.
    • 읽기 타임아웃: 외부 서비스는 성공했을 수 있음. 데이터 정합성을 위해 주기적 대사(Batch)나 성공 확인 API 호출이 필요함.
  • 외부 연동 성공, DB 처리 실패 시:
    • 외부 서비스에는 데이터가 반영되었으므로, 반드시 취소 API(보상 트랜잭션)를 호출해 상태를 되돌려야 함.
    • 취소마저 실패할 수 있으므로 주기적인 데이터 검증 프로세스가 필수적임.

2. DB 커넥션 풀

  • DB 트랜잭션 범위 안에서 외부 연동을 수행하면, 외부 서비스 응답이 늦어질 때 DB 커넥션을 계속 점유하게 됨.
  • 이로 인해 DB 부하와 상관없이 커넥션 풀 고갈(Exhaustion)이 발생하여 전체 서비스 장애로 이어질 수 있음.
  • 해결: 외부 연동은 DB 트랜잭션 범위 밖에서 수행해야 함. 단, 이 경우 실패 시 롤백 처리에 대한 명확한 정책이 필요함.

4. HTTP 커넥션 풀

  • DB 커넥션 풀과 마찬가지로, 브라우저 단에서 서버 측으로 HTTP 연결을 맺을 때 커넥션 풀을 생성하여 연결을 재사용할 수 있음.
  • 고려 사항:
    • HTTP 커넥션 풀 크기: 서버 성능이 받쳐주는 수준 하에서 적절한 크기를 선택해야 함. 무턱대고 늘리면 서버 부하로 전체 응답 시간이 저하될 수 있음.
    • 커넥션 대기 시간: 풀 크기가 3이고 요청이 4개라면, 남은 요청이 커넥션을 얻기 위해 얼마나 기다릴지 결정해야 함. (보통 1~5초 권장)
    • Keep-Alive: 한 번 맺은 HTTP 커넥션을 일정 시간 유지하여 불필요한 핸드쉐이크 비용을 줄여야 함.

이 글은 어떠셨나요? 자유롭게 의견을 남겨주세요! 💬