Нужен ли Service Discovery в Docker-среде?
В микросервисной архитектуре сервисы взаимодействуют друг с другом по HTTP или через сообщения. Один из базовых вопросов, возникающий при построении такой системы: как один сервис узнает, где находится другой?
На первый взгляд, нужно просто прописать URL другого сервиса в конфигурации и обращаться к нему напрямую. Например:
1
restTemplate.getForObject("http://profiles-service/api/profile/1", Profile.class);
Если используется Docker Compose, можно положиться на DNS-резолвинг по имени контейнера, и это действительно работает. Однако такой способ подходит не всегда. Вот как это обычно выглядит.
Когда можно обойтись без Service Discovery
Когда мы запускаем несколько сервисов через docker-compose
и объединяем их в одну сеть (например, edusphere-net
), каждый контейнер может обращаться к другим по имени сервиса. Например:
1
restTemplate.getForObject("http://profiles-service/api/users", String.class);
Это заработает без Service Discovery, если в сети edusphere-net
уже есть контейнер с именем profiles-service
. DNS внутри Docker-сети выполнит resolve.
Это значит, что внутри docker-compose можно обойтись без Discovery-сервера вообще. Нет нужды в Eureka, Consul и т.п.
В небольших проектах, особенно на стадии разработки, это может быть актуальным’:
- количество сервисов невелико;
- они запускаются совместно в одном docker-compose окружении;
- адреса сервисов фиксированы и предсказуемы.
Можно использовать прямое обращение по именам, как в примере выше.
Когда нужен Service Discovery
В более сложных сценариях:
- сервисов становится больше;
- они могут динамически масштабироваться (несколько инстансов одного сервиса);
- появляется необходимость балансировки нагрузки между экземплярами;
- окружение становится распределенным (например, Kubernetes, облако).
В таких случаях требуется система, которая отслеживает актуальные адреса и статусы всех сервисов, а также предоставляет клиентам возможность находить доступные инстансы автоматически.
Такой системой является Service Discovery. Примеры реализаций:
- Eureka — от Netflix, часто используется в Spring Boot;
- Consul — от HashiCorp;
- Встроенный DNS Service Discovery в Kubernetes.
Нужен ли Discovery в каждом проекте?
Нет. На старте часто имеет смысл не использовать Service Discovery вовсе. Это снижает сложность и ускоряет запуск. Однако при масштабировании важно предусмотреть возможность интеграции Discovery позже — например, через Spring Cloud и @EnableEurekaClient
.
Сценарий | Service Discovery нужен? |
---|---|
Локальная разработка в Docker Compose | Нет |
Монолит с выделением 2–3 сервисов | Нет |
Микросервисы в облаке или K8s | Да |
Нагрузочные кластеры и автоскейлинг | Да |
Статьи серии
- Микросервисы: серия материалов о принципах, паттернах и практике
- Эволюция архитектур: от монолита к микросервисам
- Микросервисная архитектура
- Изоляция данных и Feign: архитектура без сквозных связей
- Вызов других микросервисов с помощью Feign
- Как работает Service Discovery в Spring Cloud и зачем он нужен
- API Gateway в микросервисной архитектуре
- (в разработке)