마이크로서비스 안정성을 위한 클라이언트 사이드 Resiliency(복원력) 패턴

2025. 3. 16. 13:14Spring Microservice

🚀 마이크로서비스 안정성을 위한 클라이언트 사이드 Resiliency(복원력) 패턴 정리

마이크로서비스 아키텍처가 점점 복잡해지면서, 원격 자원(Remote Resource)을 호출하는 과정에서 발생하는 성능 저하나 장애 상황을 관리하는 것이 중요해졌습니다. 특히 클라이언트(소비자 마이크로서비스)가 다른 마이크로서비스나 데이터베이스 같은 원격 자원과 통신할 때, 이 원격 자원이 오류나 성능 문제로 실패할 때 전체 시스템으로 문제가 확산되지 않도록 보호하는 장치가 필요합니다.

이때 등장하는 개념이 바로 클라이언트 사이드 복원력(Client-side Resiliency) 패턴입니다.

🌟 이 패턴들은 원격 자원이 실패할 때 빠르게 실패(fail fast)하고, 클라이언트가 소중한 리소스(데이터베이스 연결, 쓰레드 풀 등)를 낭비하지 않게 도와줍니다.

이번 글에서는 대표적인 네 가지 패턴에 대해 자세히 살펴보겠습니다.

📌 클라이언트 측 로드 밸런싱(Client-side load balancing)
📌 서킷 브레이커(Circuit breaker)
📌 폴백(Fallback)
📌 벌크헤드(Bulkhead)

 

아래 그림은 이 네 가지 패턴이 서비스 소비자와 원격 마이크로서비스 사이에 어떤 위치에서 작동하는지 나타냅니다.

출처 : Spring Microservices in Action 2nd Edition

 

📍 1. 클라이언트 측 로드 밸런싱 (Client-side Load Balancing)

클라이언트 측 로드 밸런싱은 이전 포스팅에서 서비스 디스커버리(Service Discovery)를 다룰 때 소개했던 개념입니다. 서비스 디스커버리(예: Netflix Eureka)를 통해 서비스 인스턴스의 물리적 위치를 확인하고, 이를 클라이언트가 캐싱하여 관리합니다.

서비스 호출 시, 클라이언트는 로드 밸런서를 통해 캐싱된 서비스 인스턴스 풀에서 위치 정보를 받아 호출을 수행합니다. 만약 특정 서비스 인스턴스가 오류나 성능 문제가 있는 것으로 감지되면, 로드 밸런서는 해당 인스턴스를 풀에서 제거하여 향후 호출이 문제 있는 인스턴스로 가지 않도록 보호합니다. 🛡️

Spring Cloud Load Balancer 라이브러리는 추가 설정 없이도 위와 같은 동작을 자동으로 제공합니다.

 

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

서킷 브레이커 패턴은 전기 회로의 차단기에서 영감을 얻었습니다. 🔌 전기 회로에서는 너무 많은 전류가 흐르면 차단기가 즉시 전기를 차단하여 시스템 전체를 보호합니다.

소프트웨어의 서킷 브레이커 역시 원격 서비스 호출 시 호출 상태를 지속적으로 모니터링합니다. 만약 원격 서비스가 너무 오랜 시간이 걸리거나 실패가 일정 횟수 이상 반복되면 서킷 브레이커가 동작하여 연결을 끊고, 더 이상의 호출이 이루어지지 않도록 차단합니다. 이러한 빠른 실패 처리(Fail Fast)는 클라이언트의 리소스를 절약하고, 전체 시스템의 안정성을 보장합니다.

 

📍 3. 폴백 프로세싱 (Fallback Processing)

폴백 패턴은 원격 서비스 호출이 실패할 경우 예외(Exception)를 발생시키는 대신, 미리 정해둔 대체 코드 경로(Alternative Code Path)를 실행하여 서비스를 계속 제공합니다. 🔄

예를 들어, 전자상거래 사이트에서 사용자의 구매 이력을 분석하여 추천 목록을 제공하는 서비스가 있다고 가정해보죠. 만약 사용자의 개인 맞춤형 추천 서비스가 실패하면, 폴백 패턴을 통해 일반 사용자 집단 전체의 구매 이력을 기반으로 한 보다 일반적인 추천 목록을 제공할 수 있습니다. 이 대체 데이터는 원본과 전혀 다른 데이터 소스에서 가져올 수도 있습니다.

이를 통해 사용자는 서비스 장애 상황에서도 원활한 사용자 경험(UX)을 유지할 수 있습니다.

 

📍 4. 벌크헤드 패턴 (Bulkhead Pattern)

벌크헤드 패턴은 선박 건조 분야에서 온 개념입니다. 🚢 선박은 내부가 완전히 방수된 구획(벌크헤드)으로 나누어져 있습니다. 하나의 구획이 손상되더라도 물이 전체 선박으로 퍼지는 것을 막아 침몰을 방지합니다.

소프트웨어에서도 동일한 개념이 적용됩니다. 한 서비스가 여러 원격 자원을 호출해야 할 때, 이 호출을 독립적인 쓰레드 풀(Thread Pool)로 분리하여 관리합니다. 만약 특정 원격 자원이 성능 저하로 인해 느리게 응답하면, 그 호출만 전용 쓰레드 풀이 포화되고 다른 원격 자원 호출은 영향을 받지 않도록 보호합니다.

이처럼 쓰레드 풀은 서비스 내부의 벌크헤드 역할을 수행하며, 병목현상(bottleneck)을 효과적으로 우회하여 전체 서비스가 안정적으로 동작하게 합니다.

 

💡 Summary

지금까지 클라이언트 측 복원력 패턴 4가지(로드 밸런싱, 서킷 브레이커, 폴백, 벌크헤드)에 대해 살펴보았습니다. 각 패턴은 원격 서비스 장애 상황에서도 애플리케이션의 안정성을 유지하고, 빠른 장애 탐지 및 대처가 가능하도록 해줍니디. 💪

복잡한 마이크로서비스 환경에서 클라이언트 측 복원력 패턴을 효과적으로 적용하면, 원격 서비스 장애로 인한 연쇄적인 시스템 장애를 예방할 수 있습니다. 앞으로 마이크로서비스 설계 시 반드시 고려해야 할 중요한 설계 요소로 기억하시기 바랍니다. 🚩

 

📝 이번 포스팅의 핵심 키워드:

  • Client-side Load Balancing
  • Circuit Breaker
  • Fallback
  • Bulkhead

💻 다음 포스팅에서 더 알찬 내용으로 돌아오겠습니다! 감사합니다.