Dlaczego service discovery jest ważne?
W architekturze mikrousług aplikacje składają się z wielu niezależnych serwisów. Każdy serwis może działać na różnych maszynach, portach i może być skalowany poziomo. **Service discovery** rozwiązuje fundamentalny problem: jak serwisy mogą się nawzajem znajdować i komunikować?
Bez service discovery musielibyśmy hardkodować adresy IP i porty w konfiguracji, co jest niemożliwe w dynamicznych środowiskach cloud. To jak próba znalezienia konkretnej osoby w mieście bez książki telefonicznej.
Co się nauczysz:
- Czym różni się Eureka od Consul w praktyce
- Jak skonfigurować oba rozwiązania w Spring Boot
- Kiedy wybrać Eureka, a kiedy Consul
- Praktyczne przykłady implementacji service discovery
- Best practices dla środowisk produkcyjnych
Netflix Eureka – sprawdzony weteran
**Eureka** to service discovery opracowany przez Netflix, który stał się de facto standardem w ekosystemie Spring Cloud. Składa się z dwóch głównych komponentów:
Eureka Client – biblioteka wbudowana w każdy mikrousłuż, która rejestruje się w serwerze i pobiera informacje o innych serwisach
### Konfiguracja Eureka Server
org.springframework.cloud spring-cloud-starter-netflix-eureka-server
@SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
# application.yml server: port: 8761 eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
### Eureka Client – rejestracja serwisu
org.springframework.cloud spring-cloud-starter-netflix-eureka-client
# application.yml spring: application: name: user-service eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: preferIpAddress: true
HashiCorp Consul – wszechstronny kombajn
**Consul** to kompleksowe rozwiązanie od HashiCorp, które oferuje nie tylko service discovery, ale także distributed configuration, health monitoring i service mesh. Jest to bardziej zaawansowane narzędzie niż Eureka.
### Uruchomienie Consul
# Pobranie i uruchomienie Consul wget https://releases.hashicorp.com/consul/1.6.2/consul_1.6.2_linux_amd64.zip unzip consul_1.6.2_linux_amd64.zip ./consul agent -dev -ui -client=0.0.0.0
Lub przez Docker:
docker run -d --name=consul -p 8500:8500 consul:1.6.2 agent -server -ui -bootstrap-expect=1 -client=0.0.0.0
### Spring Cloud Consul – konfiguracja
org.springframework.cloud spring-cloud-starter-consul-discovery
# application.yml spring: application: name: order-service cloud: consul: host: localhost port: 8500 discovery: enabled: true health-check-path: /actuator/health health-check-interval: 15s
Porównanie praktyczne – co wybrać?
Aspekt | Netflix Eureka | HashiCorp Consul |
---|---|---|
Łatwość konfiguracji | Bardzo prosta – kilka annotacji | Wymaga dodatkowej infrastruktury |
Health Checks | Podstawowe, opcjonalne | Zaawansowane, wbudowane |
Configuration Store | Brak | Wbudowany KV store |
Service Mesh | Brak | Consul Connect |
Multi-datacenter | Ograniczone | Natywne wsparcie |
Overhead | Minimalny | Większy – dodatkowe komponenty |
### Komunikacja między serwisami
Oba rozwiązania umożliwiają komunikację przez nazwy serwisów zamiast hardkodowanych adresów:
@RestController public class OrderController { @Autowired private RestTemplate restTemplate; @GetMapping("/orders/{orderId}/user") public User getUserForOrder(@PathVariable String orderId) { // Zamiast http://192.168.1.10:8080/users/123 // używamy nazwy serwisu zarejestrowanego w discovery return restTemplate.getForObject( "http://user-service/users/" + getUserId(orderId), User.class ); } } @Configuration public class RestConfig { @Bean @LoadBalanced // Automatyczny load balancing! public RestTemplate restTemplate() { return new RestTemplate(); } }
Kiedy wybrać Eureka?
**Wybierz Eureka gdy:**
– Masz proste potrzeby service discovery
– Pracujesz głównie w ekosystemie Spring/Netflix
– Chcesz szybko zacząć bez dodatkowej infrastruktury
– Używasz AWS (Eureka ma świetną integrację z ELB)
– Zespół ma ograniczone doświadczenie z devops
### Przykład production-ready setup dla Eureka
# Eureka Server - application-prod.yml eureka: server: enable-self-preservation: false eviction-interval-timer-in-ms: 15000 client: register-with-eureka: false fetch-registry: false serviceUrl: defaultZone: http://eureka1:8761/eureka/,http://eureka2:8761/eureka/
Kiedy wybrać Consul?
**Wybierz Consul gdy:**
– Potrzebujesz zaawansowanych health checks
– Chcesz mieć distributed configuration w jednym miejscu
– Planujesz service mesh w przyszłości
– Masz multi-datacenter setup
– Używasz też innych technologii niż Java/Spring
### Zaawansowane możliwości Consul
# application.yml z Consul configuration spring: cloud: consul: config: enabled: true format: YAML data-key: config discovery: health-check-critical-timeout: 3m health-check-interval: 30s tags: - version=1.0 - environment=production
Testowanie service discovery
@SpringBootTest @TestPropertySource(properties = { "eureka.client.enabled=false", "spring.cloud.discovery.enabled=false" }) public class OrderServiceTest { @MockBean private DiscoveryClient discoveryClient; @Test public void shouldFindUserService() { // Given ServiceInstance userService = mock(ServiceInstance.class); when(userService.getUri()).thenReturn(URI.create("http://localhost:8080")); when(discoveryClient.getInstances("user-service")) .thenReturn(Arrays.asList(userService)); // When & Then Listinstances = discoveryClient.getInstances("user-service"); assertThat(instances).hasSize(1); } }
Teoretycznie tak – Spring Cloud pozwala na konfigurację wielu discovery clientów. W praktyce to niepotrzebna komplikacja. Wybierz jedno rozwiązanie i trzymaj się go konsekwentnie w całym projekcie.
Klienci Eureka mają lokalną cache z listą serwisów, więc mogą działać przez pewien czas bez serwera. Dla production zawsze konfiguruj klaster Eureka Serverów (minimum 2-3 instancje).
Domyślnie co 30 sekund wysyłają heartbeat. Można to skonfigurować przez eureka.instance.lease-renewal-interval-in-seconds dla Eureka lub spring.cloud.consul.discovery.health-check-interval dla Consul.
Minimalnie. Discovery klienty cachują informacje lokalnie i odświeżają je periodycznie. Pierwszy request może być nieco wolniejszy, ale kolejne używają cache.
Włącz logi DEBUG dla pakietów com.netflix.eureka lub org.springframework.cloud.consul. Sprawdź też dashboardy – Eureka ma wbudowany UI, Consul też.
Tak, ale wymaga to planowania. Najlepiej zrobić to podczas okna maintenance, zmieniając konfigurację wszystkich serwisów jednocześnie. Można też użyć dual registration na period przejściowy.
Eureka nadal dominuje w projektach Spring Boot ze względu na prostotę. Consul zyskuje popularność w środowiskach multi-platform i wszędzie tam gdzie potrzebne są zaawansowane funkcje service mesh.
Przydatne zasoby:
- Spring Cloud Netflix dokumentacja
- Consul Connect service mesh
- Netflix Eureka Wiki
- Spring Guide – Service Registration
🚀 Zadanie dla Ciebie
Stwórz prostą architekturę z dwoma serwisami (user-service i order-service) używającą Eureka do service discovery. User-service powinien zwracać dane użytkownika, a order-service powinien pobierać te dane przez discovery. Dodaj health check endpoints i przetestuj jak system zachowuje się gdy jeden z serwisów jest wyłączony.
Który system service discovery wybierasz dla swojego następnego projektu? Podziel się swoimi doświadczeniami w komentarzach – zwłaszcza jeśli miałeś okazję używać obu rozwiązań w production!