재시도 가능 조건

항상 재시도를 무작정 하면 되는건 아니다.

예를 들어 포인트 서비스가 제공하는 API를 호출해 포인트를 차감하는 상황을 생각해보자. 포인트 서비스를 호출하는 과정에서 읽기 타임아웃이 발생했을때 재시도를 하게 되면 포인트 차감이 두 번 발생할수도 있다. (에러가 뜨면 프로세스가 스탑해야되는거 아닌가?)

재시도 조건은 다음 3가지로 정리가능하다.

  • 단순 조회
  • 연결 타임아웃
  • 멱등성을 가진 변경 기능 단순 조회는 재시도로 성공 확률 높일 수 있다.

연결 타임아웃도 마찬가지. 연결 타임아웃이 발생했다는건 연동 서비스에 아직 연결이 안되었다는의미. 아직 요청한게 아무것도 없으니 처리하는것도 없다. 이러면 맘 편히 연결 재시도를 하면되지

읽기 타임아웃은 주의해야한다. 이 경우는 이미 연동 서비스가 요청을 처리하고 있는중일수도 있기때문.

상태를 변경하는 API를 재시도할 때는 멱등성을 고려해야한다. 멱등성이란 연산을 여러번 적용해도 결과가 달라지지 않는 성질을 의미한다. 예를 들어 좋아요 API 처럼 특정 콘텐츠에 사용자가 좋아요를 눌렀을 때의 처리 생각해보자.

아직 좋아요를 하기 전이면

  • (콘텐츠, 사용자) 좋아요 정보 추가한다.
  • 콘텐츠의 좋아요 수 증가 시킴
  • 200 응답 이미 좋아요 했으면 200만 응답한다.

한 사용자가 동일 컨텐츠에 여러번 좋아요 API 실행해도 좋아요는 한번만 반영된다. 이러면 읽기 타임아웃이 발생하여 재시도해도 데이터는 이상 상태 가지지 않음

재시도 횟수와 간격

재시도할 때는 다음 2가지를 결정해야됨

  • 재시도 횟수
  • 재시도 간격 재시도를 무한정 할 수 없다. 재시도 횟수 만큼 응답 시간도 함께 증가하기 때문.

재시도 간격도 중요하다. 네트웍 연결 상태가 6초간 좋지 않은 상황 가정해보자. 연동 API 호출시 3초 후 연결 타임아웃이 발생하게 된다. 이때 바로 재시도를 하면 같은 네이웍 문제로 인해 다시 연결 타임아웃이 발생할 수 있다. 반면 3초 간격 두고 재시도하면 일시적 네트웍 문제가 해소되면서 재시도가 성공할 가능성이 높아진다.

여러 차례 재시도 할때는 재시도 간격을 점진적으로 늘리기도 한다. 첫 시도는 1초 뒤, 두 번째 시도는 2초 뒤

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

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

따라서 재시도를 검토할때는 연동 서비스의 성능 상황도 함께 고려해야한다.