NYO_O

분산 통신 환경의 트래픽 최적화: 로드 밸런싱(Load Balancing) 아키텍처 본문

Architecture/MSA

분산 통신 환경의 트래픽 최적화: 로드 밸런싱(Load Balancing) 아키텍처

NYO_O 2026. 5. 26. 20:31
반응형

지난 포스팅에서는 동적으로 변하는 IP 환경에서 서비스들이 서로의 위치를 찾아낼 수 있도록 돕는 '서비스 디스커버리(Service Discovery)' 아키텍처에 대해 알아보았습니다. 이제 주문 서비스는 서비스 레지스트리(Eureka 등)를 조회하여 통신해야 할 결제 서비스의 IP 목록을 동적으로 확보할 수 있게 되었습니다.

2026.05.26 - [Tech/MSA] - MSA 환경에서 서비스 디스커버리(Service Discovery)가 필요한 이유

 

MSA 환경에서 서비스 디스커버리(Service Discovery)가 필요한 이유

정적 IP 기반 라우팅의 한계지난 포스팅에서는 거대한 모놀리식 시스템을 여러 개의 독립적인 서비스로 분리하는 마이크로서비스 아키텍처(MSA)의 개념과 도입 배경을 다루었습니다. 하지만 시

ddangnyo.tistory.com

하지만 여기서 끝이 아닙니다. 대규모 트래픽을 처리하기 위해 결제 서비스가 5대의 인스턴스로 스케일 아웃(Scale-out) 되어 있다고 가정해 보겠습니다. 주문 서비스가 레지스트리로부터 5개의 가용한 IP 목록을 응답받았을 때, 만약 로드 밸런싱 매커니즘이 없다면 주문 서비스는 첫 번째 IP로만 모든 요청을 쏟아부을 위험이 있습니다. 이는 특정 인스턴스의 자원(CPU, Memory, 커넥션 풀 등) 고갈을 유발하고 결국 해당 서버의 다운으로 이어집니다.

따라서 확보한 여러 대의 목적지 IP에 트래픽을 골고루 분배하여 시스템 전체의 안정성과 처리량을 극대화하는 메커니즘이 반드시 필요하며, 이를 로드 밸런싱(Load Balancing)이라고 부릅니다.

서버 사이드 로드 밸런싱(Server-Side Load Balancing)

물리 서버나 초기 클라우드 환경에서는 주로 '서버 사이드 로드 밸런싱' 방식을 사용했습니다. 이는 클라이언트와 타겟 서버 그룹 사이에 L4 스위치나 웹 서버(Nginx, HAProxy), 혹은 클라우드 로드밸런서(AWS ALB 등) 같은 중간 인프라 장비를 하나 두는 방식입니다.

이 구조에서 클라이언트는 타겟 서버들의 실제 IP를 전혀 알 필요가 없습니다. 오직 중간에 위치한 로드밸런서의 단일 IP 주소로만 요청을 보냅니다. 그러면 로드밸런서가 자신이 관리하는 백엔드 서버 목록 중 하나를 선택해 트래픽을 대신 전달(Proxy)합니다.

이 방식은 아키텍처가 직관적이고 애플리케이션 코드에 부하 분산 로직이 필요 없다는 장점이 있습니다. 그러나 로드밸런서 자체가 단일 장애점(SPOF)이 될 수 있으며, 모든 네트워크 트래픽이 한 곳을 거쳐 가기 때문에 네트워크 홉(Hop)이 추가되어 미세한 지연 시간(Latency)이 발생한다는 구조적 한계를 가집니다.

클라이언트 사이드 로드 밸런싱(Client-Side Load Balancing)

잘게 쪼개진 마이크로서비스 간의 내부 통신(Internal Communication)이 빈번하게 일어나는 MSA 환경에서는 중간 인프라 장비를 거치는 네트워크 홉을 최소화하는 것이 매우 중요합니다. 이를 위해 등장한 개념이 바로 '클라이언트 사이드 로드 밸런싱'입니다.

이 방식은 부하 분산의 주체가 중간 인프라 장비가 아닌 '클라이언트 애플리케이션 자체'가 됩니다. 주문 서비스(클라이언트)가 서비스 레지스트리에서 5개의 결제 서비스 IP 목록을 직접 받아온 뒤, 주문 서비스 내부에 탑재된 로드 밸런싱 라이브러리가 어떤 IP로 요청을 보낼지 알고리즘을 통해 스스로 결정합니다.

이 구조에서는 요청이 중간 프록시를 거치지 않고 타겟 서버로 다이렉트(Direct)하게 전달되므로 네트워크 지연이 최소화됩니다. 또한 중앙 집중형 로드밸런서의 병목 현상을 방지할 수 있어 대규모 분산 시스템에 훨씬 적합합니다.

라우팅 알고리즘

클라이언트 혹은 서버 사이드 로드밸런서가 타겟 인스턴스를 선택할 때는 다양한 알고리즘이 활용됩니다. 

  • 라운드 로빈(Round Robin): 가장 기본적인 방식으로, 가용 인스턴스 목록을 순회하며 요청을 순서대로 하나씩 분배합니다. 모든 서버의 처리 능력이 동일할 때 가장 효율적입니다.
  • 가중치 기반 라운드 로빈(Weighted Round Robin): 인스턴스의 사양이나 스펙이 다를 경우, 특정 서버에 더 높은 가중치를 부여하여 더 많은 트래픽이 할당되도록 조절합니다.
  • 최소 연결(Least Connections): 현재 활성화된 네트워크 커넥션(처리 중인 요청)의 수가 가장 적은 인스턴스로 새 요청을 보냅니다. 요청마다 처리 시간이 들쭉날쭉할 때 잉여 자원을 가장 효율적으로 사용할 수 있는 방식입니다.

Spring Cloud LoadBalancer와 Kubernetes 환경

과거 자바 기반의 MSA 생태계에서는 넷플릭스가 만든 Ribbon이 클라이언트 사이드 로드밸런서의 표준이었습니다. 하지만 현재는 유지보수가 중단되어, 스프링 진영에서 자체 개발한 Spring Cloud LoadBalancer가 그 자리를 대체했습니다. 이는 Eureka 등과 결합되어 코드 몇 줄만으로 라운드 로빈 기반의 스마트한 클라이언트 사이드 라우팅을 제공합니다.

한편, 최신 클라우드 네이티브의 핵심인 쿠버네티스(Kubernetes) 환경에서는 패러다임이 조금 다릅니다. 앞선 포스팅에서 언급했듯, 쿠버네티스는 내장된 DNS와 kube-proxy를 통해 서비스 간 통신을 제어합니다. 쿠버네티스의 Service 리소스를 호출하면, 개발자가 애플리케이션 코드에 클라이언트 사이드 로드밸런서를 구현하지 않아도 인프라 레벨(iptables/IPVS)에서 자동으로 타겟 파드(Pod)들에게 트래픽을 라운드 로빈 방식으로 분산시켜 줍니다.

마무리

오늘은 다수의 인스턴스로 구성된 분산 환경에서 트래픽의 병목을 막고 자원 활용도를 극대화하는 로드 밸런싱의 두 가지 아키텍처 패턴에 대해 알아보았습니다. 클라이언트 사이드 로드 밸런싱을 통해 네트워크 홉을 줄이거나, 인프라(Kubernetes)에 위임하여 복잡도를 낮추는 등 시스템 상황에 맞는 전략을 선택할 수 있게 되었습니다.

그런데 분산 통신을 구축하고 나면 또 다른 문제가 하나 남아있습니다. 주문 서비스가 2번 결제 서버로 요청을 보냈는데, 2번 서버의 데이터베이스에 데드락(Deadlock)이 발생해 응답을 주지 못한 채 무한정 대기 상태에 빠진다면 어떻게 될까요?

주문 서비스 역시 결제 응답을 기다리며 내부 스레드를 점유하게 되고, 결국 주문 서비스의 커넥션 풀마저 고갈되어 연쇄적인 시스템 장애(Cascading Failure)로 이어지게 됩니다. 다음 포스팅에서는 이러한 장애 전파를 끊어내고 시스템의 회복 탄력성(Resilience)을 보장하는 핵심 기술, '서킷 브레이커(Circuit Breaker)'에 대해 다루어 보겠습니다.

반응형