김지팡의 저장소
Published 2025. 12. 5. 17:58
API 손절하기 TIL
728x90

TL;DR

  • 우리 시스템에서 호출하고 있는 외부 API에 문제가 생긴다면?
    • 사용자 관점
    • 시스템 관점
  • CircuitBreaker 소개
    • 상태(closed, open, half-open)
  • fallback, retry

실무에서 외부 API를 호출하는 것은 비일비재하다. 어디서든 쉽게 볼 수 있는 소셜 로그인과 결제 시스템이 있고 이외에도 다양하게 외부 API를 연동한다.

 

 

🧑‍💻 그런데 만약 시스템에서 사용 중인 외부 API에 문제가 생긴다면 어떻게 될까?

당연하게도 소셜 로그인과 결제가 동작하지 않을 것이다. 이를 시스템이 외부 API에 의존하고 있다 이야기할 수 있는데, 만약 한 곳의 소셜 로그인 시스템과 한 곳의 결제 시스템에만 의존하고 있다면 정말 큰 일이다.

 

다행히도 보통의 시스템에서는 하나의 시스템에만 의존하지 않는다.

 

소셜 로그인은 ‘카카오 로그인’, ‘구글 로그인’, ‘네이버 로그인’ 등이 있고 결제 시스템은 ‘토스 페이’, ‘카카오 페이’ 등이 있다.

 

그렇기에 하나에 문제가 생겨도 치명적인 단점으로 이어지지는 않을 수 있다.

 

 

🧑‍💻 그렇게 치명적이지는 않다고???

여러 개의 창구 중 1~2개에 문제가 생겼을 때 다른 창구를 이용하면 되지 않을까라는 생각이 들 수도 있지만, 이는 사용자와 시스템 입장에서 모두 좋지 않다.

 

소셜 로그인을 생각해보면 사용자가 하나의 시스템에 여러 계정을 가지는 경우가 많지는 않다.

 

가령 이커머스를 예로 사용자 A가 계정 2개를 다른 소셜 계정(account01, account02)으로 가지고 있다 해보자.

 

account01에만 포인트가 존재하고 account02에는 결제를 한 기록이 없는 휴먼 계정인 상황에서 account01로 로그인하는 창구가 막혔다면 정말 큰일이다.

 

특별한 이유가 아니라면 사용자가 account02로 로그인해서 구매를 하거나 새로운 계정을 만들 생각이 없을 것이기 때문이다.

 

결제 시스템도 위와 마찬가지이다. 하나의 결제 방식만 고수하는 사용자가 본인이 사용하는 해당 결제 방식에 문제가 생긴다면 결제로 이어질 수가 없다. 이것 또한 큰일이다.

 

지금껏 이야기한 것들을 살펴보면 시스템에서 의존하고 있는 외부 API에 문제가 생기면 충분히 치명적이라는 것을 알 수 있다. 그뿐만 아니라 이는 곧 금전적인 손실로 이어지기도 한다.

 

그럼 사용자 입장에서 말고 시스템의 입장에서는 어떠할까?

 

 

🧑‍💻 전파되는 시스템 장애

외부 API에 의존적인 시스템에서 해당 API에 장애가 생기면 해당 기능을 사용할 수 없다. 해당 기능을 사용하지 못함으로써 얻는 단점을 제외하고 어떤 사이드 이펙트가 있을까?

 

바로 시스템 전체가 먹통이 될 수도 있다는 것인데 한 번 결제 시스템에 장애가 발생했다 가정해보자.

 

하지만 사용자는 그걸 알지 못한 채로 계속 결제를 시도한다. 이는 문제가 생겨 동작하지 않는 기능에 계속 요청을 보내고 있는 셈이다.

 

시스템마다 스레드와 커넥션의 최대 수가 정해져있기에 이러한 요청이 지속되어 쌓인다면 쓸 데 없는 스레드와 커넥션이 소비되고 이는 곧 시스템 전체에 영향을 줄 수 있게 된다.

 

 

🧑‍💻 Single Point of Failure (단일 장애 지점)

외부 API에만 장애가 생긴 것인데 왜 전체에 영향이 가게 되는 걸까?

 

API를 호출할 때 connection(db, http)이 열리는데 외부 API에 장애가 생겼다 가정해보자.

 

외부 API를 요청할 때마다 스레드는 connection을 점유하게 되는데 외부 API의 장애로 인해 점유된 connection이 반환되지 않게 될 수 있다.

 

이때 수많은 요청이 들어오게 되면 connection이 계속 점유되고 DB를 사용할 수 없는 상황이 올 수 있다. 이뿐만 아니라 외부 API를 사용하지 않는 다른 API도 같은 DB를 바라보고 있다면 장애가 전파될 수 있다.

 

이는 어느 하나의 문제로 인해 시스템 곳곳에 장애가 전파되는 문제를 야기하고, 이때 외부 API를 호출하는 곳을 SPOF(단일 장애 지점)라고 한다.

 

이를 해결하기 위해서는 어떻게 해야할까?

 

 

🧑‍💻CircuitBreaker

어느 하나의 문제가 시스템 곳곳에 영향을 줄 때 해결방법은 근본적으로는 장애 지점을 해결해야 하지만 실시간으로 돌아가는 서비스에서는 그것이 가능하진 않을 것이다.

 

그렇기 때문에 그 지점을 서비스로부터 격리를 하는 방법을 활용하여 장애가 전파되는 것을 해결하는데, 이때 사용하는 것을 CircuitBreaker라 한다.

 

CircuitBreaker는 이름에서 알 수 있듯이 회로를 차단하는 것으로 문제가 발생되는 API를 차단하는 역할을 한다.

 

CircuitBreaker의 다음 3가지의 상태를 가질 수 있는데, 설정해놓은 실패율에 따라 다음의 상태가 바뀌게 된다.

 

⦁ Closed

⦁ Open

⦁ Half-Open

 

회로 차단기가 Closed라는 것은 회로가 정상적이라는 것이기에 CircuitBreaker의 상태가 Closed인 경우에는 정상 범위이다.

 

이후 CircuitBreaker가 감시하고 있는 곳에서 장애가 발생한 것으로 판단하면 CircuitBreaker의 상태를 Open으로 변경한다.

 

Open으로 변경이 되고 나면 설정한 일정 시간동안 해당 API를 호출할 수 없게된다.

 

일정 시간이 지난 후에는 CircuitBreaker의 상태가 Half-open으로 변경되고 이때 장애가 발생했던 API를 설정한 횟수만큼 호출한다.

 

이때 실패율을 넘지 않으면 상태가 Closed로 변경이 되며 API를 다시 호출할 수 있게 되고, 실패율을 넘게 되면 다시 Open 상태로 변경이 되어 방금과 같은 동작을 반복하게 된다.

 

 

 

🧑‍💻마무리

CircuitBreaker가 무엇인지에 대해 간략하게 이야기해보았다. 에러가 발생했을 때 어떠한 메서드를 호출할 것인지를 정의하는 fallback 메서드와 에러가 발생한 API에 대해 retry를 하는 전략이 있는데 이에 대해서는 다음에 다루어보도록 하겠다.

728x90
profile

김지팡의 저장소

@김지팡

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!