본문으로 건너뛰기

1. Eureka Client 소개

  • 마이크로서비스 아키텍처에서 서비스 디스커버리는 핵심 요소입니다.
  • Eureka는 Netflix에서 개발한 서비스 디스커버리 서버로, Spring Cloud Netflix 프로젝트의 일부입니다.
  • Eureka는 Client와 Server로 구성되며, Eureka Client는 서비스를 등록하고 Eureka Server로부터 등록된 서비스 정보를 조회합니다.

2. 기본 설정

  • Eureka Client를 사용하려면 의존성을 추가하고 서비스를 등록해야 합니다.

2.1 의존성 추가

Maven 설정


<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Jersey 제외하기

기본적으로 Eureka Client는 HTTP 통신에 Jersey를 사용합니다. Jersey 의존성을 제외하고 Spring RestTemplate을 사용하려면:


<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-apache-client4</artifactId>
</exclusion>
</exclusions>
</dependency>

2.2 서비스 등록

기본 애플리케이션 설정

@SpringBootApplication
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello world";
}

public static void main(String[] args) {
new SpringApplicationBuilder(Application.class)
.web(true)
.run(args);
}
}

application.yml 설정

spring:
application:
name: my-service # 서비스 ID로 사용됨

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/ # Eureka 서버 URL
  • eureka.client.serviceUrl.defaultZone: Eureka 서버 URL의 기본값을 설정합니다.
  • spring.application.name: 서비스 ID이자 호스트명으로 사용

3. 서비스 보안 설정

3.1 Basic 인증 설정

Eureka 서버에 Basic 인증이 설정된 경우, URL에 인증정보를 포함할 수 있습니다:

eureka:
client:
serviceUrl:
defaultZone: http://user:password@localhost:8761/eureka/
제한사항

Eureka의 제한으로 서버별로 다른 인증정보를 설정할 수 없으며, 첫 번째 설정만 사용됩니다.

3.2 HTTPS 설정

HTTPS를 사용하려면 다음 설정이 필요합니다:

eureka:
instance:
securePortEnabled: true
nonSecurePortEnabled: false
statusPageUrl: https://${eureka.hostname}/info
healthCheckUrl: https://${eureka.hostname}/health
homePageUrl: https://${eureka.hostname}/

4. 상태 체크와 헬스 체크

4.1 기본 설정

eureka:
instance:
statusPageUrlPath: ${server.servletPath}/info
healthCheckUrlPath: ${server.servletPath}/health
  • statusPageUrlPath: 상태 페이지 URL 경로
  • healthCheckUrlPath: 헬스 체크 URL 경로

4.2 헬스 체크 활성화

eureka:
client:
healthcheck:
enabled: true
  • Eureka는 클라이언트 하트비트로만 클라이언트 상태를 확인합니다.
  • Discovery Client는 Spring Boot Actuator의 실제 헬스체크 상태를 전달하지 않습니다.
    • 따라서 등록이 성공하면 항상 'UP' 상태로 표시됩니다.
  • Eureka 헬스체크를 활성화하면:
    • 실제 애플리케이션 상태가 Eureka에 전달됨
    • 다른 애플리케이션들은 'UP' 상태가 아닌 서비스로 트래픽을 보내지 않음
주의사항

healthcheck.enabled 설정은 반드시 application.yml에 설정해야 합니다. bootstrap.yml에 설정하면 UNKNOWN 상태로 등록되는 등 부작용이 발생할 수 있습니다.

4.3 커스텀 헬스 체크

더 세밀한 헬스 체크가 필요한 경우 com.netflix.appinfo.HealthCheckHandler를 구현하세요:

public class CustomHealthCheckHandler implements HealthCheckHandler {
@Override
public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus current) {
// 커스텀 헬스 체크 로직 구현
return InstanceInfo.InstanceStatus.UP;
}
}

5. 메타데이터 관리

5.1 기본 메타데이터

  • Eureka 인스턴스는 다음과 같은 기본 메타데이터를 제공합니다:
    • 호스트명
    • IP 주소
    • 포트 번호
    • 상태 페이지 URL
    • 헬스 체크 URL

5.2 커스텀 메타데이터 추가

eureka:
instance:
metadata-map:
zone: zone1
customKey: customValue

6. 인스턴스 ID 설정

6.1 기본 인스턴스 ID 형식

기본적으로 Eureka 인스턴스 ID는 다음 형식을 따릅니다:

${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}

예: myhost:myappname:8080

6.2 커스텀 인스턴스 ID 설정

eureka:
instance:
instance-id: ${spring.application.name}:${random.value}

7. Eureka Client API 사용

7.1 EurekaClient 사용

@Autowired
private EurekaClient discoveryClient;

public String serviceUrl() {
InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false);
return instance.getHomePageUrl();
}
주의사항

EurekaClient는 @PostConstruct나 @Scheduled 메서드에서 사용하지 마세요. ApplicationContext 초기화가 완료되지 않은 상태일 수 있습니다.

7.2 DiscoveryClient 사용

@Autowired
private DiscoveryClient discoveryClient;

public String serviceUrl() {
List<ServiceInstance> list = discoveryClient.getInstances("STORES");
if (list != null && list.size() > 0) {
return list.get(0).getUri();
}
return null;
}

8. 서비스 등록 지연과 최적화

8.1 서비스 등록 주기

eureka:
instance:
lease-renewal-interval-in-seconds: 30 # 기본값
  • 서비스 인스턴스는 기본 30초 주기로 Eureka 서버에 하트비트를 보냅니다.
  • 서비스가 발견 가능한 상태가 되려면 인스턴스, 서버, 클라이언트 모두가 로컬 캐시에 동일한 메타데이터를 가져야 합니다(3번의 하트비트가 필요할 수 있음).
  • eureka.instance.lease-renewal-interval-in-seconds 주기를 변경할 수 있습니다.
  • 30초 미만으로 설정하면 클라이언트가 다른 서비스와 더 빨리 연결됩니다.
  • 하지만 운영 환경에서는 서버 내부 계산이 기본 갱신 주기를 가정하고 있어서 기본값을 유지하는 것이 좋습니다.

8.2 레지스트리 가져오기 주기

eureka:
client:
registry-fetch-interval-seconds: 30 # 기본값
  • 클라이언트는 30초마다 Eureka 서버에서 레지스트리 정보를 가져옵니다.
  • 운영 환경에서는 기본값(30초) 사용을 권장합니다.
  • 개발 환경에서는 더 빠른 서비스 발견을 위해 주기를 줄일 수 있습니다.
  • 주기를 줄이면 Eureka 서버 부하가 증가할 수 있으니 주의해야 합니다.

8.3 클라이언트 리프레시 설정

  • 기본적으로 EurekaClient 빈은 리프레시가 가능합니다(속성 변경/갱신 가능).
  • 리프레시 발생 시 클라이언트들이 Eureka 서버에서 등록 해제되므로, 특정 서비스의 모든 인스턴스가 일시적으로 이용 불가능할 수 있습니다.
  • 이를 방지하려면 eureka.client.refresh.enable=false로 리프레시 기능을 비활성화하면 됩니다.
eureka:
client:
refresh:
enable: false # 리프레시 기능 비활성화

9. 존(Zone) 설정

9.1 기본 존 설정

eureka:
instance:
metadataMap:
zone: zone1
client:
preferSameZoneEureka: true

9.2 Spring Cloud LoadBalancer와 통합

Spring Cloud LoadBalancer의 Zone 기반 필터링을 위한 설정:

spring:
cloud:
loadbalancer:
eureka:
approximateZoneFromHostname: true
존 데이터 소스

존 정보는 다음 순서로 결정됩니다:

  1. Eureka 인스턴스 메타데이터의 zone 값
  2. 서버 호스트네임의 도메인 이름 (approximateZoneFromHostname=true인 경우)
  3. 클라이언트 설정의 eureka.client.availabilityZones

10. AWS 환경 설정

10.1 AWS 인식 설정

@Bean
@Profile("!default")
public EurekaInstanceConfigBean eurekaInstanceConfig(InetUtils inetUtils) {
EurekaInstanceConfigBean b = new EurekaInstanceConfigBean(inetUtils);
AmazonInfo info = AmazonInfo.Builder.newBuilder().autoBuild("eureka");
b.setDataCenterInfo(info);
return b;
}

11. Cloud Foundry 환경 설정

11.1 라우터 설정

eureka:
instance:
hostname: ${vcap.application.uris[0]}
nonSecurePort: 80
instanceId: ${vcap.application.instance_id}
Cloud Foundry 특징
  • 모든 인스턴스가 동일한 호스트네임 사용
  • 글로벌 라우터를 통한 트래픽 처리
  • vcap.application.instance_id로 인스턴스 구분