클라우드 인프라

마이크로서비스, 서비스 디스커버리 어떤 방식으로 구현해야 할까?

강코의 코딩 일기 2026. 7. 26. 16:05
반응형

마이크로서비스 아키텍처에서 서비스 디스커버리 구현 방식 고민이신가요? DNS 기반과 API 기반 솔루션의 장단점을 실무 관점에서 비교하고, 예비 개발자에게 필요한 인사이트를 공유합니다.

안녕하세요, 클라우드 인프라와 마이크로서비스 아키텍처에 관심이 많은 개발자 여러분. 특히 취업이나 이직을 준비하며 면접 질문과 실제 프로젝트 환경에 대한 고민이 많으실 예비 개발자분들을 위해, 마이크로서비스 환경의 핵심 요소인 서비스 디스커버리 패턴에 대한 깊이 있는 이야기를 준비했습니다.

마이크로서비스 아키텍처는 개별 서비스들이 독립적으로 배포되고 통신하는 방식입니다. 그런데 여기서 한 가지 중요한 질문이 생깁니다. 수많은 서비스 인스턴스들이 끊임없이 생성되고 사라지는 상황에서, 어떻게 다른 서비스의 위치를 정확히 알고 통신할 수 있을까요? 바로 이 문제에 대한 해답이 서비스 디스커버리입니다. 제가 직접 여러 프로젝트에서 다양한 방식을 적용해보고 얻은 경험을 바탕으로, DNS 기반API 기반 솔루션의 장단점, 그리고 실제 구현 방식까지 낱낱이 비교 분석해 드리겠습니다. 면접관의 질문 의도를 파악하고 실무 역량을 어필하는 데 큰 도움이 될 것이라고 확신합니다.


📑 목차

마이크로서비스 환경의 서비스 디스커버리 패턴: DNS 기반과 API 기반 솔루션의 장단점 및 구현 방식 비교 - europe, iceland, location, highway, road, journey, travel, adventure, landscape, mountains, clouds, sky, nature, freedom, escape, wanderlust, open road, driving, perspective, distance, horizon, discovery, transportation, infrastructure

Image by 8moments on Pixabay

1. 마이크로서비스 환경에서 서비스 디스커버리가 왜 중요할까요?

마이크로서비스 아키텍처를 도입하는 이유는 확장성과 유연성, 그리고 개발팀의 독립성을 확보하기 위함입니다. 하지만 이러한 장점 뒤에는 복잡성이라는 그림자가 따라옵니다. 모놀리식 애플리케이션에서는 모든 컴포넌트가 하나의 프로세스 내에 존재했기 때문에 서로를 호출하는 것이 간단했습니다. 그러나 마이크로서비스에서는 각 서비스가 네트워크를 통해 통신해야 합니다.

서비스 인스턴스의 동적 변화와 통신 문제

실제로 서비스를 운영하다 보면, 특정 서비스의 로드가 증가하여 인스턴스를 수평 확장하거나, 장애가 발생하여 특정 인스턴스가 종료되고 새로운 인스턴스가 다시 시작되는 일이 비일비재합니다. 이렇게 서비스 인스턴스의 IP 주소와 포트 번호가 끊임없이 변동하게 되는데, 다른 서비스들이 이러한 변화를 실시간으로 인지하고 올바른 대상을 찾아 통신하는 것이 매우 중요합니다. 만약 서비스 디스커버리 메커니즘이 없다면, 서비스 A가 서비스 B를 호출하려고 할 때, 서비스 B의 현재 IP 주소를 일일이 수동으로 관리하거나 하드코딩해야 하는 비효율적인 상황에 직면하게 됩니다. 이는 결국 시스템의 안정성을 저해하고 유지보수 비용을 폭증시키는 결과를 초래합니다.

제가 처음 마이크로서비스 프로젝트에 참여했을 때, 초기에는 서비스 인스턴스가 몇 개 되지 않아 수동으로 관리하는 것이 가능할 것이라고 생각했습니다. 하지만 서비스 수가 10개를 넘어가고 각 서비스의 인스턴스가 3개 이상으로 늘어나자, 개발자들은 끊임없이 변경되는 IP 주소 때문에 디버깅에만 엄청난 시간을 소모했습니다. 결국 서비스 디스커버리 솔루션 도입은 선택이 아닌 필수가 되었습니다.


2. DNS 기반 서비스 디스커버리: 그 심플함 뒤편

DNS 기반 서비스 디스커버리는 가장 전통적이고 널리 사용되는 방식 중 하나입니다. 기본적으로 DNS(Domain Name System)는 도메인 이름을 IP 주소로 변환해주는 역할을 합니다. 이 원리를 서비스 디스커버리에 적용하는 것입니다.

작동 원리 및 특징

이 방식은 각 마이크로서비스 인스턴스가 시작될 때, 자신의 IP 주소와 포트 정보를 DNS 서버에 등록합니다. 이때 보통 서비스 이름을 도메인처럼 사용하여 {서비스명}.{도메인} 형식으로 등록합니다. 예를 들어, user-service.internal.example.com과 같은 형태입니다. 다른 서비스가 user-service를 호출해야 할 때, 이 도메인 이름을 DNS 서버에 질의하여 현재 가용한 user-service 인스턴스의 IP 주소를 응답받아 통신합니다.

제가 실제 클라우드 환경에서 이 방식을 적용했을 때, 가장 큰 장점은 그 단순성이었습니다. 특별한 서비스 디스커버리 서버를 구축할 필요 없이, 이미 존재하는 DNS 인프라(예: AWS Route 53, Kubernetes의 CoreDNS)를 활용할 수 있었습니다. 덕분에 초기 설정 비용과 복잡성이 현저히 낮아졌죠.


# DNS 기반 서비스 디스커버리 예시 (Linux 터미널)
# user-service.internal.example.com 의 IP 주소 질의
dig +short user-service.internal.example.com

# 출력 예시:
# 10.0.1.10
# 10.0.1.11
# 10.0.1.12

위 예시처럼 DNS 서버는 여러 IP 주소를 반환하여 클라이언트가 로드 밸런싱을 수행할 수 있게 하거나, DNS 자체의 라운드 로빈 기능을 활용할 수 있습니다. 이는 장애 격리에도 도움이 됩니다. 특정 인스턴스에 문제가 생기면 DNS 레코드에서 해당 IP를 제거하여 더 이상 트래픽이 가지 않도록 할 수 있습니다.

장점과 단점

  • 장점:
    • 단순성: 별도의 복잡한 서비스 디스커버리 서버가 필요 없습니다. 기존 DNS 인프라를 활용합니다.
    • 표준화: DNS는 인터넷의 표준 기술이므로, 대부분의 시스템이 이를 이해하고 활용할 수 있습니다.
    • 캐싱: DNS 쿼리 결과는 클라이언트나 중간 DNS 서버에 캐싱될 수 있어 성능 향상에 기여합니다.
  • 단점:
    • 느린 전파 속도: 인스턴스의 변경 사항(생성/삭제/장애)이 DNS 레코드에 반영되고 클라이언트에 전파되는 데 시간이 걸릴 수 있습니다 (TTL, Time To Live). 이로 인해 오래된 정보를 바탕으로 통신을 시도하는 문제가 발생할 수 있습니다.
    • 헬스 체크의 한계: DNS는 서비스 인스턴스의 세부적인 헬스 체크 상태를 파악하고 반영하기 어렵습니다. 단순히 IP 주소만 관리하므로, 인스턴스는 살아있지만 애플리케이션 내부에서 문제가 발생한 경우를 감지하기 어렵습니다.
    • 추가 정보 부족: 서비스 인스턴스에 대한 IP 주소 외의 메타데이터(예: 버전, 가용 영역)를 제공하기 어렵습니다.
    • 클라이언트 사이드 로드 밸런싱의 어려움: 여러 IP가 반환될 때 클라이언트가 직접 로드 밸런싱 로직을 구현해야 할 수 있습니다.

면접에서 DNS 기반 방식에 대해 질문받는다면, "DNS는 익숙하고 단순하지만, 동적인 마이크로서비스 환경에서는 TTL 문제로 인해 서비스 상태 변화를 즉각적으로 반영하기 어렵다는 단점이 있습니다. 특히 장애 발생 시 서비스 중단 시간이 길어질 수 있습니다"와 같이 핵심적인 장단점을 명확히 설명하는 것이 중요합니다.


3. API 기반 서비스 디스커버리: 유연함과 제어의 힘

API 기반 서비스 디스커버리서비스 디스커버리 서버(또는 레지스트리)라는 중앙 집중식 컴포넌트를 사용하여 서비스 인스턴스의 등록 및 조회를 관리하는 방식입니다. 이 방식은 DNS 기반 방식의 한계를 극복하고 더 많은 유연성과 제어 기능을 제공합니다.

작동 원리 및 특징

이 방식에서는 각 마이크로서비스 인스턴스가 시작될 때, 자신의 IP 주소, 포트, 그리고 기타 메타데이터(예: 서비스 버전, 배포 환경, 가용 영역)를 서비스 디스커버리 서버에 등록합니다. 서비스 인스턴스는 주기적으로 헬스 체크(Heartbeat) 신호를 서버에 보내 자신이 정상적으로 작동하고 있음을 알립니다. 만약 일정 시간 동안 헬스 체크 신호가 오지 않으면, 서버는 해당 인스턴스를 서비스 목록에서 제거합니다.

다른 서비스가 특정 서비스를 호출해야 할 때, 먼저 서비스 디스커버리 서버에 API 요청을 보내 호출하려는 서비스의 가용한 인스턴스 목록을 조회합니다. 서버는 헬스 체크를 통과한 인스턴스 목록을 반환하며, 클라이언트는 이 목록 중에서 적절한 인스턴스를 선택하여 통신합니다. 이 과정에서 클라이언트 사이드 로드 밸런싱(Client-Side Load Balancing)이 함께 이루어지는 경우가 많습니다.

제가 경험한 프로젝트에서는 Netflix EurekaHashiCorp Consul 같은 솔루션을 많이 활용했습니다. 특히 Eureka를 적용했을 때, 서비스 인스턴스들이 실시간으로 등록되고 해제되는 것을 대시보드를 통해 직접 확인할 수 있었습니다. DNS 방식으로는 알 수 없었던 서비스 인스턴스의 상세 상태 정보(UP/DOWN)를 명확하게 파악할 수 있었던 점이 인상 깊었습니다.


// API 기반 서비스 디스커버리 (예: Spring Cloud Eureka 클라이언트 코드)
@SpringBootApplication
@EnableEurekaClient // Eureka 클라이언트로 작동하도록 설정
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

// 다른 서비스에서 UserService를 호출하는 예시
@Service
public class OrderService {
    @Autowired
    private DiscoveryClient discoveryClient; // Eureka에서 서비스 인스턴스 목록 조회

    public String callUserService() {
        List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
        if (instances != null && !instances.isEmpty()) {
            ServiceInstance instance = instances.get(0); // 간단하게 첫 번째 인스턴스 선택
            String url = instance.getUri().toString() + "/api/users";
            // RestTemplate 또는 WebClient로 호출
            return "Calling user-service at: " + url;
        }
        return "user-service not found";
    }
}

위 코드처럼 클라이언트 라이브러리가 서비스 디스커버리 서버와의 통신을 추상화하여 개발자가 쉽게 사용할 수 있도록 돕습니다. 이를 통해 개발자는 서비스의 위치를 하드코딩할 필요 없이 서비스 이름만으로 통신할 수 있습니다.

장점과 단점

  • 장점:
    • 실시간 업데이트 및 정확성: 헬스 체크를 통해 서비스 인스턴스의 상태 변화를 즉각적으로 감지하고 반영합니다. 장애 발생 시 빠르게 해당 인스턴스를 제거하여 트래픽이 가지 않도록 합니다.
    • 풍부한 메타데이터: IP 주소 외에 서비스 버전, 가용 영역, 특정 태그 등 다양한 메타데이터를 등록하고 조회할 수 있어 유연한 라우팅 및 필터링이 가능합니다.
    • 클라이언트 사이드 로드 밸런싱: 클라이언트가 직접 인스턴스 목록을 받아와 다양한 로드 밸런싱 전략(라운드 로빈, 최소 연결 등)을 적용할 수 있습니다.
    • 유연한 쿼리: 서비스 이름 외에 메타데이터를 기반으로 인스턴스를 조회하는 등 더 복잡한 쿼리가 가능합니다.
  • 단점:
    • 추가적인 인프라 필요: 서비스 디스커버리 서버(예: Eureka 서버, Consul 서버)를 별도로 구축하고 관리해야 합니다. 이는 추가적인 운영 부담과 비용을 발생시킵니다.
    • 단일 장애점 가능성: 서비스 디스커버리 서버 자체가 단일 장애점이 될 수 있습니다. 따라서 고가용성(High Availability)을 위해 클러스터 구성이 필수적입니다.
    • 클라이언트 라이브러리 종속성: 서비스를 개발할 때 해당 서비스 디스커버리 솔루션의 클라이언트 라이브러리에 의존해야 합니다. 이는 특정 기술 스택에 묶일 수 있습니다.
    • 네트워크 트래픽 증가: 헬스 체크 신호, 서비스 등록/조회 API 호출 등으로 인해 네트워크 트래픽이 증가할 수 있습니다.

API 기반 방식은 DNS 방식보다 복잡하지만, 마이크로서비스 환경의 동적인 특성과 요구사항에 훨씬 더 잘 부합합니다. 특히 서비스 인스턴스의 정확한 상태 관리와 유연한 라우팅이 필요한 대규모 시스템에서는 거의 필수적으로 사용됩니다.


마이크로서비스 환경의 서비스 디스커버리 패턴: DNS 기반과 API 기반 솔루션의 장단점 및 구현 방식 비교 - cloud, infrastructure, disk space, computing power, application software, internet, web, service, hand, storage, chalk, to paint, heaven, infrastructure, infrastructure, infrastructure, infrastructure, infrastructure

Image by geralt on Pixabay

4. 두 가지 방식, 그래서 어떤 선택이 합리적일까요?

지금까지 DNS 기반API 기반 서비스 디스커버리의 작동 방식과 장단점을 살펴보았습니다. 그렇다면 실제로 어떤 상황에서 어떤 방식을 선택해야 할까요? 제가 여러 프로젝트를 경험하며 내린 결론은 '정답은 없지만, 상황에 따른 최적의 선택은 있다'는 것입니다.

핵심 비교 요소

두 방식을 주요 비교 요소별로 정리하면 다음과 같습니다.

비교 항목 DNS 기반 서비스 디스커버리 API 기반 서비스 디스커버리
복잡성 낮음 (기존 DNS 인프라 활용) 높음 (별도 디스커버리 서버 구축 및 관리)
실시간성 (상태 변화 반영) 느림 (DNS TTL에 의존) 빠름 (실시간 헬스 체크 및 API 갱신)
헬스 체크 제한적 (IP 가용성 위주, 애플리케이션 레벨 체크 어려움) 정교함 (애플리케이션 레벨 헬스 체크 가능)
메타데이터 활용 불가능 (IP 주소 위주) 가능 (서비스 버전, 가용 영역 등 활용)
로드 밸런싱 DNS 라운드 로빈 또는 클라이언트 구현 클라이언트 사이드 로드 밸런싱 (다양한 전략)
운영 오버헤드 낮음 높음 (디스커버리 서버 고가용성 관리)
적합한 환경 정적 또는 변화가 적은 서비스, 소규모 마이크로서비스 동적이고 복잡한 대규모 마이크로서비스, 클라우드 네이티브 환경

실제 적용 시 고려사항

제가 프로젝트에 적용하면서 느낀 가장 중요한 점은 시스템의 규모와 동적인 변화의 정도였습니다. 작은 규모의 마이크로서비스(예: 5개 미만의 서비스)에서는 DNS 기반 방식만으로도 충분히 운영이 가능했습니다. 특히 Kubernetes 같은 컨테이너 오케스트레이션 플랫폼을 사용한다면, CoreDNS가 내장되어 있어 별도의 노력 없이도 DNS 기반 서비스 디스커버리를 활용할 수 있습니다. 실제로 많은 클라우드 네이티브 환경에서는 Kubernetes의 Service 리소스를 통해 DNS 기반 디스커버리를 효과적으로 사용합니다.

하지만 서비스 수가 20개를 넘어가고, 각 서비스의 인스턴스가 수시로 스케일 아웃/인되는 대규모 환경에서는 API 기반 방식이 훨씬 강력했습니다. 예를 들어, 특정 서비스의 버전을 A/B 테스트하거나, 특정 가용 영역에 배포된 인스턴스만으로 트래픽을 라우팅해야 하는 복잡한 요구사항이 생길 때는 메타데이터 기반의 유연한 조회가 필수적이었습니다. Netflix EurekaHashiCorp Consul 같은 솔루션은 이러한 요구사항을 충족시키면서 안정적인 운영을 가능하게 했습니다.

특히 클라우드 네이티브 환경에서는 서비스 메시(Service Mesh)와 연동하여 서비스 디스커버리를 더욱 고도화할 수 있습니다. Istio 같은 서비스 메시는 내부적으로 Envoy 프록시를 통해 서비스 디스커버리 서버(예: Consul, Kubernetes API 서버)와 연동하여 트래픽 라우팅을 자동으로 처리합니다. 이는 개발자가 서비스 디스커버리 로직을 직접 구현할 필요 없이 네트워크 레벨에서 모든 것이 처리되도록 돕습니다.


5. 실전 구현 가이드: DNS 기반 vs. API 기반

이론적인 비교를 넘어, 실제 프로젝트에서 두 방식을 어떻게 구현할 수 있는지 간단한 가이드라인을 제시해 드리겠습니다.

DNS 기반 디스커버리 구현 (Kubernetes 환경 예시)

Kubernetes는 컨테이너 오케스트레이션 플랫폼으로서, DNS 기반 서비스 디스커버리를 기본적으로 제공합니다. 별도의 서비스 디스커버리 서버를 구축할 필요가 없다는 것이 큰 장점입니다.

작동 방식: Kubernetes에서 Pod를 배포하고 Service 리소스를 생성하면, CoreDNS가 자동으로 해당 서비스의 DNS 레코드를 생성합니다. 다른 Pod는 이 서비스 이름을 사용하여 해당 서비스의 Pod 인스턴스에 접근할 수 있습니다.


# user-service 배포 (Deployment)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: your-repo/user-service:1.0
        ports:
        - containerPort: 8080

---

# user-service 노출 (Service)
apiVersion: v1
kind: Service
metadata:
  name: user-service # 이 이름이 DNS 이름이 됩니다
spec:
  selector:
    app: user-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP # 클러스터 내부에서만 접근 가능

위 YAML 파일을 배포하면, user-service라는 DNS 이름으로 user-service-deployment의 Pod 인스턴스들에 접근할 수 있습니다. 예를 들어, 다른 서비스의 Pod에서 http://user-service/api/users와 같이 호출하면 자동으로 로드 밸런싱되어 user-service의 가용한 인스턴스 중 하나로 트래픽이 전달됩니다. CoreDNS는 Pod의 생성/삭제를 감지하여 DNS 레코드를 실시간으로 업데이트합니다. 단, DNS TTL 설정에 따라 변경 사항이 전파되는 데 약간의 지연이 있을 수 있습니다.

API 기반 디스커버리 구현 (Netflix Eureka & Spring Cloud 예시)

API 기반 디스커버리의 대표적인 예시인 Netflix EurekaSpring Cloud를 활용한 구현 방식을 소개합니다.

1. Eureka Server 구축: 먼저 Eureka Server를 구축해야 합니다. 이는 별도의 Spring Boot 애플리케이션으로 간단하게 만들 수 있습니다.


// EurekaServerApplication.java
@SpringBootApplication
@EnableEurekaServer // Eureka 서버로 작동하도록 설정
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

application.yml에 Eureka 서버 설정을 추가합니다.


# application.yml (Eureka Server)
server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false # 자신을 레지스트리에 등록하지 않음
    fetch-registry: false # 레지스트리 정보를 가져오지 않음
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

2. Eureka Client 서비스 구현: 다음으로, 서비스 디스커버리의 대상이 되는 마이크로서비스(예: user-service)를 Eureka 클라이언트로 만듭니다.


// UserServiceApplication.java
@SpringBootApplication
@EnableEurekaClient // Eureka 클라이언트로 작동하도록 설정
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

application.yml에 Eureka 클라이언트 설정을 추가합니다.


# application.yml (UserService)
spring:
  application:
    name: user-service # Eureka에 등록될 서비스 이름

server:
  port: 8080 # 이 서비스의 포트

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/ # Eureka 서버 주소
  instance:
    prefer-ip-address: true # IP 주소로 등록 (선택 사항)

이렇게 설정된 user-service는 시작될 때 localhost:8761Eureka 서버에 자신의 정보(user-service라는 이름, IP, 포트)를 등록하고 주기적으로 헬스 체크 신호를 보냅니다.

3. 다른 서비스에서 호출: 다른 서비스(예: order-service)에서 user-service를 호출할 때는 Spring Cloud LoadBalancer(또는 Ribbon)와 DiscoveryClient를 활용합니다.


// OrderService.java (일부)
@Service
public class OrderService {

    private final RestTemplate restTemplate;

    public OrderService(RestTemplateBuilder builder) {
        // @LoadBalanced 어노테이션이 붙은 RestTemplate 빈을 주입받아 사용
        // 이 RestTemplate은 Eureka 서버에서 user-service의 인스턴스 목록을 가져와
        // 클라이언트 사이드 로드 밸런싱을 자동으로 수행합니다.
        this.restTemplate = builder.build();
    }

    public String getUserInfo(Long userId) {
        // 서비스 이름으로 호출
        String url = "http://user-service/api/users/" + userId;
        return restTemplate.getForObject(url, String.class);
    }
}

@LoadBalanced 어노테이션이 붙은 RestTemplate을 사용하면, 개발자는 서비스 이름을 URL에 직접 사용하여 서비스 디스커버리로드 밸런싱을 자동으로 처리할 수 있습니다. 이 방식은 메타데이터 기반의 라우팅, 정확한 헬스 체크 등 API 기반 디스커버리의 모든 장점을 활용할 수 있습니다.


마이크로서비스 환경의 서비스 디스커버리 패턴: DNS 기반과 API 기반 솔루션의 장단점 및 구현 방식 비교 - bee, insect, pollination, nature, wings, entomology, beekeeping, world bee day, bee, bee, bee, bee, bee

Image by RiaanMarais on Pixabay

6. 면접에서 서비스 디스커버리, 어떻게 답변할까요?

취업/이직 면접에서 서비스 디스커버리마이크로서비스 관련 질문에서 매우 빈번하게 등장하는 주제입니다. 면접관은 단순히 개념을 아는지 묻는 것을 넘어, 실제 문제 해결 능력과 시스템 설계에 대한 이해도를 파악하고자 합니다.

면접관의 질문 의도 파악

면접관이 서비스 디스커버리에 대해 묻는다면, 대개 다음과 같은 의도를 가집니다.

  • 마이크로서비스 아키텍처의 이해도:서비스 디스커버리가 필요한지, 어떤 문제를 해결하는지 아는가?
  • 다양한 솔루션에 대한 지식: 어떤 종류의 서비스 디스커버리 패턴이 있고, 각 방식의 장단점은 무엇인가?
  • 실무 적용 경험 및 판단력: 특정 상황에서 어떤 방식을 선택할지, 그 근거는 무엇인지 설명할 수 있는가?
  • 클라우드 환경 이해: Kubernetes 등 클라우드 환경에서 서비스 디스커버리가 어떻게 작동하는지 아는가?

예상 질문과 답변 전략

Q1: 마이크로서비스 환경에서 서비스 디스커버리가 왜 필요한가요?

A1: "마이크로서비스는 서비스 인스턴스가 동적으로 생성되고 사라지며 IP 주소와 포트가 계속 변동합니다. 서비스 디스커버리는 이러한 동적인 환경에서 다른 서비스의 위치를 실시간으로 찾아 통신할 수 있도록 해줍니다. 이를 통해 서비스 간의 결합도를 낮추고, 시스템의 확장성과 유연성, 안정성을 확보할 수 있습니다. 수동으로 IP를 관리하는 비효율성을 해소하고, 서비스 장애 시에도 빠르게 대응하여 중단 시간을 최소화하는 핵심적인 역할을 합니다."

Q2: 서비스 디스커버리 방식에는 어떤 것들이 있으며, 각 방식의 장단점을 설명해 주세요.

A2: "크게 DNS 기반API 기반 두 가지 방식이 있습니다. DNS 기반은 기존 DNS 인프라를 활용하여 구현이 간단하고 친숙하다는 장점이 있지만, TTL 문제로 인해 서비스 상태 변화를 즉각적으로 반영하기 어렵고, 헬스 체크가 제한적이라는 단점이 있습니다. 반면 API 기반Netflix EurekaHashiCorp Consul 같은 별도의 서비스 디스커버리 서버를 구축해야 하므로 복잡성이 있지만, 실시간 헬스 체크를 통해 정확한 서비스 상태를 반영하고 메타데이터 기반의 유연한 조회가 가능하며, 클라이언트 사이드 로드 밸런싱을 지원한다는 강력한 장점이 있습니다."

Q3: 실제 프로젝트에서는 어떤 방식을 적용했고, 왜 그 방식을 선택했나요?

A3: (본인의 경험을 바탕으로 구체적으로 답변) "제가 참여했던 [프로젝트명]에서는 [서비스 개수]개의 마이크로서비스를 운영했습니다. 초기에는 [선택한 방식: 예: DNS 기반]을 고려했지만, [단점 또는 특정 요구사항: 예: 서비스 인스턴스의 잦은 변경과 복잡한 라우팅 요구사항] 때문에 [최종 선택한 방식: 예: API 기반 솔루션인 Netflix Eureka]를 도입했습니다. Eureka를 통해 실시간 헬스 체크메타데이터 기반의 라우팅을 구현하여, 서비스 인스턴스에 문제가 발생했을 때 자동으로 트래픽을 우회하고, 특정 버전의 서비스로만 트래픽을 보내는 A/B 테스트 같은 고급 기능을 효과적으로 적용할 수 있었습니다. 물론 Eureka 서버의 고가용성 구성에 대한 운영 부담은 있었지만, 시스템의 안정성과 유연성 측면에서 훨씬 큰 이점을 얻었습니다."

Q4: Kubernetes 환경에서는 서비스 디스커버리를 어떻게 구현하나요?

A4: "Kubernetes는 기본적으로 DNS 기반 서비스 디스커버리를 강력하게 지원합니다. Deployment로 Pod를 배포하고 Service 리소스를 생성하면, CoreDNS가 자동으로 해당 서비스의 DNS 레코드를 생성합니다. 다른 Pod들은 이 서비스 이름을 사용하여 내부적으로 클러스터 IP를 통해 통신할 수 있으며, Kubernetes Service는 자동으로 로드 밸런싱 역할을 수행합니다. 따라서 대부분의 경우 Kubernetes 내에서는 별도의 API 기반 디스커버리 서버 없이도 효과적인 서비스 디스커버리가 가능합니다. 더 복잡한 라우팅이나 정책이 필요할 경우 서비스 메시(Service Mesh)와 같은 기술을 추가적으로 고려할 수 있습니다."

이러한 답변 전략을 통해 단순히 지식을 나열하는 것을 넘어, 본인의 경험과 깊이 있는 이해를 면접관에게 전달할 수 있을 것입니다.


마무리하며: 당신의 마이크로서비스 여정을 응원합니다

지금까지 마이크로서비스 환경의 핵심인 서비스 디스커버리 패턴, 특히 DNS 기반API 기반 솔루션의 장단점과 구현 방식을 실무 경험과 면접 관점에서 깊이 있게 살펴보았습니다. 어떤 방식이든 완벽한 정답은 없으며, 팀의 기술 스택, 시스템의 규모, 요구되는 동적 유연성 등 여러 요소를 고려하여 최적의 선택을 내리는 것이 중요합니다.

예비 개발자 여러분, 이러한 깊이 있는 고민과 이해는 면접에서 당신을 돋보이게 할 뿐만 아니라, 실제로 복잡한 마이크로서비스 아키텍처를 설계하고 운영하는 데 필수적인 역량이 될 것입니다. 서비스 디스커버리는 단순한 기술이 아니라, 분산 시스템의 복잡성을 관리하고 안정성을 확보하는 중요한 '지능'과 같습니다.

이 글이 여러분의 마이크로서비스 여정에 작은 이정표가 되기를 바랍니다. 궁금한 점이나 여러분의 경험이 있다면 댓글로 자유롭게 공유해주세요. 함께 성장하는 개발 커뮤니티를 만들어가요!

📌 함께 읽으면 좋은 글

  • [클라우드 인프라] 트래픽 폭증에 대비하는 데이터베이스 확장, 직접 해보니 이 방법이 통했습니다
  • [기술 리뷰] 금융 시스템 오류 보고서, 0.000000001의 오차가 초래한 결과
  • [클라우드 인프라] CDK와 Pulumi, 과도한 추상화의 덫: 재사용성인가, 복잡성인가?

이 글이 도움이 되셨다면 공감(♥)댓글로 응원해 주세요!
궁금한 점이나 다루었으면 하는 주제가 있다면 댓글로 남겨주세요.

반응형