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

JJinu·2025년 11월 21일

Books

목록 보기
1/2
post-thumbnail

이 포스팅은 최범균 저자님의 '주니어 백엔드 개발자가 반드시 알아야 할 실무 지식' 책을 읽고 기록해 두기 위해 작성하였습니다.

개발을 하다보면 결제가 필요하면 PortOne이나 카카오페이, 토스페이 등 각자의 외부 연동이 필요합니다. 이 때 살펴보아야 할 것들은 무엇이 있을까요?

0. 우리는 문제가 없는데...?

개발자가 아무리 대규모 트래픽 경험이 있고 트래픽 처리 경험이 뛰어나더라도 외부 서비스와 연동을 하며 외부 서비스가 몰려드는 트래픽이 감당하지 못하면서 장애가 발생할 수 있습니다.
외부 서비스를 줄이면 좋겠지만 필수인 경우도 있기 때문에 연동 서비스의 문제로 인한 영향을 줄이는 방법을 찾아보겠습니다.

타임아웃 (Connection Timeout, Read Timeout)

외부 연동에서 가장 중요한 설정 중 하나는 타임아웃입니다.타임아웃은 응답시간과 깊이 관련되어 있습니다. 연동 서비스를 호출할 때 타임아웃을 적절히 설정하지 않으면, 연동 서비스에 장애가 발생했을 때 전체 서비스의 품질이 급격히 나빠질 수 있습니다.

예를 들어, A서비스는 톰캣을 사용하고 있으며 스레드 풀 크기는 200이라면 A서비스는 동시에 200개의 요청을 처리할 수 있다고 했을 때,

A서비스가 B서비스를 호출했지만 B서비스에 문제가 생겨 응답 시간이 1분을 넘기기 시작했다면 동시에 200개의 요청을 처리할 수 있더라도 B서비스의 응답대기로 인해 처리량이 급격하게 떨어질 수 있습니다. 또한 이후의 요청이 B서비스와 연관이 없는 요청이라도 이 또한 처리하지 못하게 됩니다.

사용자 입장에서는 어떻게 될까?

사용자는 응답을 기다리면서 무작정 기다릴 수 밖에 없습니다. 하지만 사용자는 오래 기다려주지 않습니다.
구글 리서치 자료에 따르면, 아래와 같은 이탈률을 보인다고 나와있습니다.

3초 이상: 이탈률 32% 증가
5초 이상: 이탈률 90% 증가
6초 이상: 이탈률 106% 증가
10초 이상: 이탈률 123% 증가

그렇다면 사용자를 덜 화나게(화를 안낼 수는 없겠죠..?)하는 방법은..! 에러를 보여주는 것 입니다. 반응없는 무한 대기 보다 에러 화면이라도 보여주는것이 더 낫습니다. 또한 서버는 사용자 요청에 대해 자원이 포화되기 전에 응답하게 되므로, 연동 서비스 문제가 다른 기능에 주는 여향을 줄일 수 있다는 장점도 있습니다.

재시도

네트워크 통신 과정에서 간헐적으로 연결에 실패하거나 일시적으로 응답이 느려지는 경우가 있습니다. 이럴 때는 재시도를 통해 연동 실패를 성공으로 바꿀 수 있습니다.

재시도 가능 조건

재시도를 통해 연동 실패를 줄일 수 있지만, 항상 재시도를 할 수 있는 것은 아닙니다. 조건을 확인해 봐야죠..!

재시도 조건 3가지

1. 단순 조회 기능
2. 연결 타임아웃
3. 멱등성(Idempotent)을 가진 변경 기능

단순 조회 기능은 재시도를 통해 성공 확률을 높일 수 있습니다. 예를들어 상용자 포인트 내역 조회같은 기능은 다시 호출해도 포인트 중복 차감같은 데이터 문제가 생기지 않기때문에 일시적인 문제였다면 다시 조회할 경우 정상적으로 처리될 가능성이 높습니다.

연결 타임아웃도 마찬가지로 연동 서비스가 요청을 처리하고 있지 않은 상태이므로, 순간적인 네트워크 문제였다면 재시도를 통해 연결이 성공할 가능성이 있습니다.

읽기 타임아웃은 재시도 할 때 주의해야 합니다.이 경우는 이미 연동 서비스가 요청을 처리하고 있는 중이기 때문에 읽기 타임아웃이 발생한 상황에서 재시도를 하면 문제가 생길 수 있습니다.

멱등성 = 연산을 여러번 적용해도 결과가 달라지지 않는 성질을 말합니다.
데이터 변경이 이루어지는 재시도 때에는 멱등성을 가지는 변경인지 확인하여야 합니다.

재시도 결정 조건

1. 재시도 횟수
2. 재시도 간격

재시도는 무한정 할 수는 없습니다. 재시도 횟수만큼 응답시간도 함께 증가하기 때문에 대부분의 경우 1~2번 정도의 재시도가 적당합니다. 모든 재시도가 실패하였다면 간헐적인 오류보다는 다른 근본적인 문제일 가능성이 높아 다시 재시도해도 실패할 확률이 높습니다.

또한 재시도 간격도 중요합니다. 만약 네트워크 연결 상태가 6초간 좋지 않은 상황을 가정해봤을 때, 바로 재시도 하면 같은 네트워크 문제로 인해 다시 연결 타임아웃이 발생할 수 있습니다. 그렇기에 재시도 간격도 생각해보면 좋겠습니다.

재시도를 통해 성공 가능성을 높일 수 있지만, 반대로 연동 서비스에는 더 큰 부하를 줄 수 있으니, 재시도를 검토할 때는 연동 서비스의 성능 상황도 함께 고려해보면 좋겠습니다.

서킷 브레이커

연동 서비스에 과부하가 발생해 응답을 제대로 주지 못하고 있는 상황이라고 해봅시다. 연동 서비스가 정상화되기 전까지는 요청을 보내도 계속 에러만 발생합니다. 또한, 읽기 타임아웃이 발생할 때까지 대기하느라 응답 시간도 길어질 것입니다. 즉, 연동 서비스가 장애일 때 요청을 보내도 에러만 발생합니다.

이러한 상황일 때에는, B서비스에 요청을 보내지 않고 바로 에러를 응답하는 것이 좋습니다. 사용자 입장에서도 수 초를 대기하다가 에러화면을 보는 것 보다 빠르게 에러화면을 보는 편이 낫겠죠?

이렇듯 연동 서비스가 장애 상황일 때는 연동 대신 바로 에러를 응답하고, 정상화되었을 때 연동을 재개하면 연동 서비스의 장애가 주는 영향을 줄일 수 있습니다.

서킷브레이커는 누전 차단기와 비슷하게 생각하면 좋을 것 같습니다. 과전류가 흐르면 차단기가 내려가 전기를 끊는 것처럼, 과도한 오류가 발생하면 연동을 중지시키고 바로 에러를 응답합니다.
서킷브레이커는 닫힘, 열림, 반 열림 3가지 상태를 가집니다.

  • 닫힘 (Closed)
    서킷 브레이커는 닫힘 상태로 시작합니다. 이 상태는 모든 요청을 연동 서비스에 전달합니다.
  • 열림 (Open)
    연동요청을 수행하지 않고, 바로 에러 응답을 보냅니다. 열림 상태는 지정된 시간 동안 유지되며, 이 시간이 지나면 반 열림 상태로 전환됩니다.
  • 반 열림 (Half-Open)
    일부 요청에 한해 연동을 시도합니다. 일정 개수 또는 일정 시간 동안 반 열림 상태를 유지하며, 이 기간동안 연동에 성공하면 닫힘 상태로 복귀합니다. 반대로 실패하면 열림 상태로 전환되어 연동을 차단합니다.

이외에도 외부서비스로 인한 성능 감소시 고려해야할 다양한 것들(HTTP 커넥션 풀, 연동 서비스 이중화 , ...)이 많이 있으니 서비스 상황에 맞게 경험해보고 적용하면서 적절한 방법을 찾아나가 보면 좋겠습니다!!

profile
하루하루 의미있고 행복하게! (Yesterday is History, Tomorrow is a mystery, But today is a gift)

0개의 댓글