공부/Architecture

Service Discovery 개념에 대해 알아보자

d02 2024. 9. 8. 17:52

Service Discovery 패턴

배경

MSA의 분산 환경은 서비스 간 원격 통신으로 동작한다. 아래와 같은 이유로 다른 서비스의 정확한 위치(IP와 포트)를 직접 알고 있지 않고도 서비스 간 통신을 할 필요가 생겼다.

  • cloud 환경에서 가상화/컨테이너화되어 동작하며, 인스턴스의 개수와 위치는 동적으로 변화한다. 또 각 인스턴스는 언제든지 제거/중지될 수도 있다.
  • 예를 들어 오토 스케일링에 따라 인스턴스가 계속 바뀌기 때문에 서비스에서 매번 각 인스턴스의 위치와, 어느 인스턴스가 살아있는지를 직접 알고 있을 순 없다.

이렇게 언제든 바뀔 수 있는 서비스 위치들을 각 서비스들이 직접 알아야 한다면, 이는 클라우드 환경의 방향성과 도 맞지 않고 유지보수하기 어려운 시스템 구조가 될 것이다.

 

정의

이러한 배경에서 서비스 클라이언트에서 다른 서비스를 호출할 때, 서비스의 위치를 알아낼 수 있도록 하는 패턴을 Service Discovery라고 한다.
각 인스턴스들을 추적하여, 일종의 주소록처럼 Service Registry를 관리하면서 위치를 제공하는 것이다.

이미지 출처:  https://www.baeldung.com/cs/service-discovery-microservices

DNS 레코드에 호스트 명 - 여러 개의 IP를 매핑시킬 수도 있지만, 레코드 삭제 시 업데이트 되는 시간 등이 소요되는 문제가 있으며, 굳이 직접 그렇게 하지 않아도 현재 이미 많은 솔루션들이 제공되고 있다. (zookeeper, eureka)

 

Server side discovery & Client side discovery

Service Discovery의 구현 방식은 서버 사이드, 클라이언트 사이드 두 가지로 나누어볼 수 있다.

Server side discovery

서비스 앞에서 로드 밸런서 역할을 하는 프록시 서버에서 registry를 조회해온다. 프록시 서버는 위치 정보를 기반으로 요청을 라우팅한다.

  • AWS의 ELB, 구글 클라우드의 로드 밸런서가 이와 같은 방식으로 동작한다.
  • 장점: 디스커버리 로직을 클라이언트 쪽에서 알 필요가 없으며, 각 서비스마다 서비스 레지스트리를 구현할 필요 없다.
  • 단점: 서비스 디스커버리가 죽으면 전체 시스템이 동작하지 않으므로 고가용성을 위한 관리가 필요하다.

이미지 출처:  https://www.baeldung.com/cs/service-discovery-microservices

Client side discovery

서비스 소비처(클라이언트)에서 registry를 직접 조회하고, 로드밸런싱을 구현하여 요청하는 방식이다.

  • Netflix 오픈소스인 Eureka, Ribbon과 같은 라이브러리를 사용하여 구현 가능하다.
  • Kafka에서는 zookeeper가 메타 데이터를 가지고 서비스 레지스트리 역할을 한다. Producer, Consumer가 zookeeper를 통해 현재 사용 가능한 브로커가 있음을 알 수 있다.
  • 장점: 각 서비스에 맞는 로드 밸런싱 방식을 각각 구현할 수 있다.
  • 단점: 각 서비스마다 서비스 레지스트리를 구현해야 하는 종속성이 생긴다.

이미지 출처:  https://www.baeldung.com/cs/service-discovery-microservices

일반적인 비즈니스 기능 동작을 위한 API 통신 상황을 생각하면 나에게는 서버 사이드 방식이 더 익숙하게 느껴진다.

각 서비스 별 로드 밸런싱을 세세하게 조절할 필요가 없고, 로드 밸런서의 고가용성을 지킬 수 있는 환경이라면 클라이언트와 서비스 디스커버리의 종속성이 필요 없는 서버 사이드 방식이 더 좋아보인다.

다만 비즈니스 기능 동작 외에도, 분산 환경에서 서비스 디스커버리 개념은 다양하게 사용될 수 있을 것이다.
예를 들어 SPOF 방지를 위하여 특정 서비스의 중지 처리를 하기 위해서는 특정 서비스의 모든 인스턴스 위치를 알아야 한다. 이 때, 클라이언트 측에서 서비스 레지스트리를 조회해 중지하는 기능을 구현할 수 있을 것이다.

 

Spring Cloud 제공 인터페이스

Spring Cloud는 분산 시스템에서 필요한 다양한 기능들을 추상화하여 제공하고 있다.

이미지 출처: https://spring.io/cloud

서비스 디스커버리도 이 중 하나로, DiscoveryClient를 비롯한 여러 인터페이스를 제공한다.
이를 Netflix OSS의 Eureka, Apache ZooKeeper, Consul 과 같은 구현체와 연동하여 사용할 수 있다.
물론, 서비스 디스커버리란 포괄적인 어떤 개념이기 때문에 필요에 맞게 직접 이 인터페이스를 구현한 구현체를 사용할 수도 있을 것이다.

 

DiscoveryClient

package org.springframework.cloud.client.discovery;  

import java.util.List;  
import org.springframework.cloud.client.ServiceInstance;  
import org.springframework.core.Ordered;  

public interface DiscoveryClient extends Ordered {  
    int DEFAULT_ORDER = 0;  

    String description();  

    List<ServiceInstance> getInstances(String serviceId);  

    List<String> getServices();  

    default void probe() {  
        this.getServices();  
    }  

    default int getOrder() {  
        return 0;  
    }  
}

참고 자료

반응형