재시도 - 외부 연동 실패시 방법 중 하나

재시도 가능 조건

  • 항상 재시도를 무작정 하면 되는건 아님
  • 예를 들어 포인트 서비스가 제공하는 API를 호출해 포인트를 차감하는 상황을 생각해보자
    • 포인트 서비스를 호출하는 과정에서 읽기 타임아웃이 발생했을때 재시도를 하게 되면 포인트 차감이 두 번 발생할수도 있다
    • 타임아웃은 우리 시스템이 세팅한 제한시간이 끝나면 발생하기에, 외부 시스템은 결국 포인트가 차감되는 경우를 상상하면 됨
  • 재시도 조건은 다음 3가지로 정리가능
    • 단순 조회
    • 연결 타임아웃
    • 멱등성을 가진 변경 기능
  • 연결 타임아웃이 발생했다는건 연동 서비스에 아직 연결이 안되었다는 의미
  • 아직 요청한게 아무것도 없으니 처리하는것도 없다
  • 이러면 맘 편히 연결 재시도를 하면됨
  • 읽기 타임아웃은 주의
  • 이 경우는 이미 연동 서비스가 요청을 처리하고 있는중 일수도 있기 때문
  • 상태를 변경하는 API를 재시도할 때는 멱등성을 고려해야함
  • 멱등성이란 연산을 여러번 적용해도 결과가 달라지지 않는 성질을 의미
  • 예를 들어 좋아요 API 처럼 특정 콘텐츠에 사용자가 좋아요를 눌렀을 때의 처리 생각해보자
    • 아직 좋아요를 하기 전이면
      • (콘텐츠, 사용자) 좋아요 정보 추가한다
      • 콘텐츠의 좋아요 수 증가 시킴
      • 200 응답
      • 이미 좋아요 했으면 200만 응답하면됨
  • 한 사용자가 동일 컨텐츠에 여러번 좋아요 API 실행해도 좋아요는 한번만 반영
  • 이러면 읽기 타임아웃이 발생하여 재시도해도 데이터는 이상 상태 가지지 않음

재시도 횟수와 간격

  • 재시도할 때는 다음 2가지를 결정해야됨
    • 재시도 횟수
    • 재시도 간격
  • 재시도를 무한정 할 수 없다
    • 재시도 횟수 만큼 응답 시간도 함께 증가하기 때문
  • 재시도 간격도 중요
    • 네트웍 연결 상태가 6초간 좋지 않은 상황 가정해보자
    • 연동 API 호출시 3초 후 연결 타임아웃이 발생하게 됨
    • 이때 바로 재시도를 하면 같은 네트웍 문제로 인해 다시 연결 타임아웃이 발생할 수 있다
    • 반면 3초 간격 두고 재시도하면 일시적 네트웍 문제가 해소되면서 재시도가 성공할 가능성이 높아짐
    • 여러 차례 재시도 할때는 재시도 간격을 점진적으로 늘리기도 한다
    • 첫 시도는 1초 뒤, 두 번째 시도는 2초 뒤

재시도 폭풍(retry storm) 안티패턴

  • 재시도로 성공 가능성 높일 수 있지만, 반대로 연동 서비스에는 더 큰 부하를 줄 수 있다
  • 예를 들어 성능이 느려져서 읽기 타임아웃이 발생한 상황 생각 ㄱ
    • 이렇게 재시도하면 연동 서비스는 같은 요청을 두 배로 받게됨
    • 이전 요청 아직 처리중인데 같은 클라가 재시도로 또다시 요청을 보내는 것임
  • 따라서 재시도를 검토할때는 연동 서비스의 성능 상황도 함께 고려해야한다.