PHpullh
학습 라이브러리/Java/서비스 디스커버리

JAVA · 디자인패턴

서비스 디스커버리

마이크로서비스가 서로를 동적으로 찾는 서비스 디스커버리 패턴입니다.

디자인패턴고급ServiceDiscovery서비스디스커버리레지스트리로드밸런싱

핵심 설명

마이크로서비스가 서로를 동적으로 찾는 서비스 디스커버리 패턴입니다.

Java code

import java.util.*;
import java.util.concurrent.*;

public class ServiceDiscovery {
    record ServiceInstance(String id, String host, int port, boolean healthy) {}

    // 서비스 레지스트리
    static class Registry {
        private final Map<String, List<ServiceInstance>> services =
            new ConcurrentHashMap<>();
        private int roundRobin = 0;

        // 서비스 등록
        void register(String name, ServiceInstance instance) {
            services.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>())
                    .add(instance);
            System.out.printf("등록: %s -> %s:%d%n", name, instance.host(), instance.port());
        }

        // 서비스 해제
        void deregister(String name, String instanceId) {
            List<ServiceInstance> list = services.get(name);
            if (list != null) {
                list.removeIf(i -> i.id().equals(instanceId));
            }
        }

        // 서비스 발견 (라운드 로빈 로드 밸런싱)
        Optional<ServiceInstance> discover(String name) {
            List<ServiceInstance> list = services.get(name);
            if (list == null || list.isEmpty()) return Optional.empty();

            List<ServiceInstance> healthy = list.stream()
                .filter(ServiceInstance::healthy).toList();
            if (healthy.isEmpty()) return Optional.empty();

            int idx = Math.abs(roundRobin++) % healthy.size();
            return Optional.of(healthy.get(idx));
        }
    }

    public static void main(String[] args) {
        Registry registry = new Registry();
        registry.register("user-service",
            new ServiceInstance("u1", "10.0.0.1", 8080, true));
        registry.register("user-service",
            new ServiceInstance("u2", "10.0.0.2", 8080, true));

        for (int i = 0; i < 4; i++) {
            registry.discover("user-service").ifPresent(inst ->
                System.out.printf("발견: %s:%d%n", inst.host(), inst.port()));
        }
    }
}

학습 팁

클라이언트 사이드 디스커버리(Netflix Eureka)와 서버 사이드 디스커버리(Kubernetes DNS)의 차이를 이해하세요.

주의할 점

헬스 체크 없이 인스턴스를 반환하면 장애 서버로 트래픽이 전달됩니다. 주기적 헬스 체크와 비정상 인스턴스 제거가 필수입니다.

자주 묻는 질문

서비스 디스커버리란 무엇인가요?

마이크로서비스가 서로를 동적으로 찾는 서비스 디스커버리 패턴입니다.

서비스 디스커버리 학습 시 주의할 점은 무엇인가요?

헬스 체크 없이 인스턴스를 반환하면 장애 서버로 트래픽이 전달됩니다. 주기적 헬스 체크와 비정상 인스턴스 제거가 필수입니다.