2024. 9. 10. 21:26ㆍMSA/Eureka
2024/09/10
고민 끝에 찰나의 깨달음을 얻으신 경험이 다들 있으신가요?
아주 오래 전 아르키메데스는 왕에게
왕관이 진짜 순금인지를 알아오라는 명을 받습니다.
고민을 하던 아르키메데스는 목욕탕에서 넘치는 물을 보고는 '유레카!'라고 외치죠.

넷플릭스에서 개발한 서비스 디스커버리 서버인 유레카도
어쩌면 마이크로서비스 아키텍처를 어떻게 관리하면 좋을 지
고민 끝에 딱 떠오르는 아이디어로 탄생한게 아닐까요?
오늘은 서비스 디스커버리와 유레카에 대해 알아봅시다.
※ 서비스 디스커버리와 Eureka에 대해 알아보자.
▶ 서비스 디스커버리 개요
● 서비스 디스커버리란?
○ 서비스 디스커버리는 마이크로서비스 아키텍처에서 각 서비스의 위치를 동적으로 관리하고 찾아주는 기능
○ 각 서비스는 등록 서버에 자신의 위치를 등록하고, 다른 서비스는이를 조회하여 통신한다.
○ 주요 기능으로는 서비스 등록, 서비스 조회, 헬스 체크 등이 있다.
▶ Eureka 개요
● Eureka?
○ 넷플릭스가 개발한 서비스 디스커버리 서버로, 마이크로서비스 아키텍처에서 각 서비스의 위치를 동적으로 관리
○ 모든 서비스 인스턴스의 위치를 저장하는 중앙 저장소 역할을 하며, 서비스 인스턴스의 상태를 주기적으로 확인하여 가용성을 보장한다.
○ 여러 인스턴스를 지원하여 고가용성을 유지할 수 있다.
● Eureka 서버 설정
○ Eureka 서버는 서비스 레지스트리를 구성하는 중앙 서버
📌 서버 설정 파일 예시
YAML
server:
port: 8761
eureka:
client:
register-with-eureka: false # 다른 Eureka 서버에 이 서버를 등록하지 않음
fetch-registry: false # 다른 Eureka 서버의 레지스트리를 가져오지 않음
server:
enable-self-preservation: false # 자기 보호 모드 비활성화
○ 해당 설정을 통해 Eureka 서버를 구성하고, 클라이언트가 등록할 수 있도록 준비한다.
● Eureka 클라이언트 설정
○ 각 서비스는 Eureka 서버에 자신을 등록해야 한다.
○ spring-cloud-starter-netflix-eureka-client 의존성을 사용하고, 애플리케이션 이름만 설정파일에 있으면 Eureka에 등록된다.
📌 클라이언트 설정 파일 예시
YAML
spring:
application:
name: my-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/ # Eureka 서버 URL
register-with-eureka: true # Eureka 서버에 등록
fetch-registry: true # Eureka 서버로부터 레지스트리 정보 가져오기
instance:
hostname: localhost # 클라이언트 호스트 이름
prefer-ip-address: true # IP 주소 사용 선호
lease-renewal-interval-in-seconds: 30 # 리스 갱신 간격
lease-expiration-duration-in-seconds: 90 # 리스 만료 기간
▶ 서비스 등록 및 디스커버리
● 서비스 등록
○ 각 서비스 애플리케이션은 Eureka 서버에 자신의 위치를 등록한다.
○ spring-cloud-starter-netflix-eureka-client 의존성을 사용하고, 애플리케이션 이름만 설정파일에 있으면 Eureka에 등록된다.
● 서비스 디스커버리
○ 클라이언트 애플리케이션은 Eureka 서버에서 필요한 서비스의 위치를 조회한다.
📌 RestTemplate을 사용하는 경우
✅ 클라이언트 애플리케이션은 Eureka 서버에서 필요한 서비스의 위치를 조회한다.
✅ Spring Boot 애플리케이션에서 @LoadBalanced 애노테이션을 사용하여 RestTemplate에 로드 밸런싱 기능을 추가한다.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@RestController
public class MyRestTemplateController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/get-data-rest")
public String getDataWithRestTemplate() {
String serviceUrl = "http://my-service/api/data";
return restTemplate.getForObject(serviceUrl, String.class);
}
}
📌 FeignClient을 사용하는 경우
✅ 클라이언트 애플리케이션은 Eureka 서버에서 필요한 서비스의 위치를 조회한다.
✅ Spring Boot 애플리케이션에서 FeignClient를 사용하여 간편하게 서비스 호출을 수행한다.
@SpringBootApplication
@EnableFeignClients
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@FeignClient(name = "my-service")
public interface MyServiceClient {
@GetMapping("/api/data")
String getData();
}
@RestController
public class MyFeignClientController {
@Autowired
private MyServiceClient myServiceClient;
@GetMapping("/get-data-feign")
public String getDataWithFeignClient() {
return myServiceClient.getData();
}
}
● 헬스 체크 및 장애 처리
○ 헬스 체크
➡️ Eureka 서버가 주기적으로 서비스 인스턴스의 상태를 확인하여 가용성을 유지한다.
➡️ 기본 헬스 체크 엔드포인트 /actuator/health 를 사용한다.
○ 장애 처리
➡️ 서비스 장애 시 Eureka 서버는 해당 인스턴스를 레지스트리에서 제거하여 다른 서비스의 접근을 차단한다.
▶ Eureka의 고가용성 구성
● 클러스터 구성
○ Eureka 서버의 고가용성을 위해 여러 인스턴스를 구성할 수 있다.
○ 다중 인스턴스로 구성하여 고가용성을 유지하며, 각 인스턴스는 서로를 피어로 등록하여 상호 백업한다.
📌 설정 파일 예시
YAML
eureka:
client:
service-url:
defaultZone: http://eureka-peer1:8761/eureka/,http://eureka-peer2:8761/eureka/
○ Eureka 서버를 다중 인스턴스로 구성할 때 각 서버의 피어 설정을 통해 서로를 인식하고 백업할 수 있다.