Eureka Service Discovery
Mikroservis mimarisinde servisler dinamiktir — yeni instance'lar başlar, eskiler kapanır, IP adresleri değişir. Servislerin birbirini bulması için sabit IP/port kullanmak yerine bir Service Discovery mekanizması kullanılır. Netflix Eureka, bu amaçla en yaygın kullanılan çözümdür. Bu derste Eureka Server kurulumunu, client kaydını ve client-side load balancing'i detaylı inceleyeceğiz.
Service Discovery Nedir?
Geleneksel yapıda servis adresleri konfigürasyon dosyalarında hardcode edilir:
# order-service application.yml
user-service:
url: http://192.168.1.10:8081 # IP değişirse ne olacak?Bu yaklaşımın sorunları açıktır: IP adresleri değiştiğinde, yeni instance eklendiğinde veya bir instance kapandığında konfigürasyonun güncellenmesi gerekir. Service Discovery bu sorunu otomatikleştirir.
Eureka iki bileşenden oluşur:
Eureka Server — Servis kayıt defteri. Tüm servislerin adreslerini tutar.
Eureka Client — Kendini server'a kaydeden ve diğer servisleri sorgulayan uygulama.
Eureka Server Kurulumu
Yeni bir Spring Boot projesi oluşturun:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>Ana sınıf:
@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:
register-with-eureka: false # kendini kaydetme
fetch-registry: false # başkalarını sorgulama
server:
enable-self-preservation: true
eviction-interval-timer-in-ms: 5000register-with-eureka: false ve fetch-registry: false — Eureka Server'ın kendisi bir servis değildir, sadece kayıt defteridir. Kendini kaydetmesi veya başkalarını sorgulaması gerekmez.
Başlatıldığında http://localhost:8761 adresinde Eureka Dashboard görüntülenir. Bu dashboard, kayıtlı tüm servisleri, instance'ları ve durumlarını gösterir.
Eureka Client (Servis Kaydı)
Her mikroservis Eureka Client olarak çalışır. Dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>application.yml:
spring:
application:
name: user-service # Eureka'daki servis adı
server:
port: 8081
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true # hostname yerine IP kullan
instance-id: ${spring.application.name}:${server.port}@EnableDiscoveryClient annotasyonu artık Spring Boot 3.x'te otomatik olarak uygulanır — dependency eklenmesi yeterlidir. Ancak açıkça belirtmek istiyorsanız:
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}Servis Kaydı Yaşam Döngüsü
1. User Service başlar → Eureka Server'a kayıt isteği gönderir
2. Eureka Server kaydı kabul eder → registry'e ekler
3. User Service her 30 saniyede heartbeat gönderir (lease renewal)
4. Eureka Server 90 saniye heartbeat almazsa → instance'ı siler
5. Diğer servisler Eureka'dan user-service adresini sorgularClient-Side Load Balancing
Birden fazla instance varsa (örneğin user-service 3 instance çalışıyor), isteklerin dengeli dağıtılması gerekir. Spring Cloud LoadBalancer bunu otomatik yapar:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>@Configuration
public class RestClientConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}@LoadBalanced annotasyonu, RestTemplate'e load balancing özelliği kazandırır. Artık IP adresi yerine servis adını kullanabilirsiniz:
@Service
public class OrderService {
private final RestTemplate restTemplate;
public OrderService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public UserDto getUser(Long userId) {
// "user-service" Eureka'daki servis adı
// LoadBalancer otomatik olarak mevcut instance'lardan birine yönlendirir
return restTemplate.getForObject(
"http://user-service/api/users/{id}",
UserDto.class, userId);
}
}Load balancing stratejileri:
Round Robin (varsayılan) — İstekler sırayla her instance'a dağıtılır
Random — Rastgele bir instance seçilir
// Özel load balancing stratejisi
@Configuration
public class CustomLoadBalancerConfig {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHealthChecks()
.build(context);
}
}Eureka High Availability
Production ortamda tek bir Eureka Server tek hata noktası (SPOF) olur. Çözüm: birden fazla Eureka Server'ın birbirini kaydederek çalışması:
# eureka-server-1 (port 8761)
eureka:
client:
service-url:
defaultZone: http://localhost:8762/eureka/
# eureka-server-2 (port 8762)
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/Client'lar her iki sunucuyu da bilir:
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/Eureka, mikroservis mimarisinin temel yapı taşıdır. Servislerin birbirini dinamik olarak keşfetmesini ve load balancing ile yüksek erişilebilirlik sağlamasını mümkün kılar.
AI Asistan
Sorularını yanıtlamaya hazır