Eureka: 서비스 레지스트리 및 검색 시스템 구축 🚀
마이크로서비스 아키텍처가 현대 소프트웨어 개발의 중심으로 자리 잡으면서, 서비스 디스커버리와 로드 밸런싱의 중요성이 더욱 부각되고 있습니다. 이러한 환경에서 Netflix Eureka는 강력하고 신뢰할 수 있는 서비스 레지스트리 및 검색 시스템으로 주목받고 있습니다. 이 글에서는 Eureka의 개념부터 구축 방법, 그리고 실제 운영에 이르기까지 상세히 다루어 보겠습니다. 🌟
💡 Tip: Eureka를 통한 서비스 레지스트리 구축은 마이크로서비스 아키텍처의 핵심 요소입니다. 이는 재능넷과 같은 복잡한 플랫폼에서 특히 유용할 수 있으며, 다양한 서비스 간의 원활한 통신과 확장성을 보장합니다.
1. Eureka 개요
Eureka는 AWS 클라우드에서 중간 계층 서버의 로드 밸런싱과 페일오버를 목적으로 Netflix에서 개발한 REST 기반 서비스입니다. 주요 특징은 다음과 같습니다:
- 서비스 등록 및 해제의 자동화
- 상태 모니터링을 통한 서비스 가용성 확인
- 분산 시스템에서의 고가용성 보장
- 클라이언트 측 로드 밸런싱 지원
Eureka는 서비스 인스턴스의 동적인 추가 및 제거를 지원하여, 클라우드 환경에서의 탄력적인 확장을 가능하게 합니다.
위 다이어그램은 Eureka 서버를 중심으로 여러 마이크로서비스가 등록되고 상호작용하는 모습을 보여줍니다. 각 서비스는 Eureka 서버에 자신의 정보를 등록하고, 필요할 때 다른 서비스의 정보를 조회할 수 있습니다.
2. Eureka 서버 구축
Eureka 서버를 구축하는 과정은 다음과 같습니다:
- Spring Boot 프로젝트 생성
- 의존성 추가
- 애플리케이션 설정
- Eureka 서버 활성화
2.1 Spring Boot 프로젝트 생성
Spring Initializr를 사용하여 새로운 Spring Boot 프로젝트를 생성합니다. 프로젝트 생성 시 다음 설정을 선택합니다:
- Project: Maven Project
- Language: Java
- Spring Boot: 2.5.x 이상
- Packaging: Jar
- Java: 11 이상
2.2 의존성 추가
pom.xml 파일에 Eureka 서버 의존성을 추가합니다:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
또한, Spring Cloud 버전을 관리하기 위해 다음 속성을 추가합니다:
<properties>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.3 애플리케이션 설정
application.properties 또는 application.yml 파일에 Eureka 서버 설정을 추가합니다:
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.server.wait-time-in-ms-when-sync-empty=0
이 설정은 다음을 의미합니다:
- 서버 포트를 8761로 설정 (Eureka의 기본 포트)
- 자기 자신을 Eureka 서버에 등록하지 않도록 설정
- 레지스트리 정보를 로컬에 캐싱하지 않도록 설정
- 초기 동기화 대기 시간을 0으로 설정
2.4 Eureka 서버 활성화
메인 애플리케이션 클래스에 @EnableEurekaServer 어노테이션을 추가하여 Eureka 서버를 활성화합니다:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
이제 애플리케이션을 실행하면 Eureka 서버가 구동됩니다. 브라우저에서 http://localhost:8761로 접속하면 Eureka 대시보드를 확인할 수 있습니다.
3. Eureka 클라이언트 구현
Eureka 서버가 준비되었다면, 이제 Eureka 클라이언트를 구현하여 서비스를 등록해 보겠습니다. Eureka 클라이언트는 서비스 인스턴스를 Eureka 서버에 등록하고, 필요할 때 다른 서비스의 정보를 조회하는 역할을 합니다.
3.1 클라이언트 프로젝트 설정
새로운 Spring Boot 프로젝트를 생성하고, 다음 의존성을 추가합니다:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
3.2 애플리케이션 설정
application.properties 또는 application.yml 파일에 다음 설정을 추가합니다:
spring.application.name=my-service
server.port=8080
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
이 설정은 다음을 의미합니다:
- 서비스 이름을 'my-service'로 설정
- 서비스 포트를 8080으로 설정
- Eureka 서버의 URL을 지정
3.3 Eureka 클라이언트 활성화
메인 애플리케이션 클래스에 @EnableDiscoveryClient 어노테이션을 추가하여 Eureka 클라이언트를 활성화합니다:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class MyServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MyServiceApplication.class, args);
}
}
이제 애플리케이션을 실행하면 자동으로 Eureka 서버에 등록됩니다. Eureka 대시보드에서 등록된 서비스를 확인할 수 있습니다.
4. Eureka의 고가용성 구성
실제 운영 환경에서는 단일 Eureka 서버로는 충분하지 않습니다. 고가용성을 보장하기 위해 Eureka 서버를 클러스터로 구성해야 합니다. 이를 통해 한 서버가 다운되더라도 시스템이 계속 작동할 수 있습니다.
4.1 Eureka 서버 클러스터 구성
Eureka 서버 클러스터를 구성하려면 각 서버가 서로를 인식하도록 설정해야 합니다. 예를 들어, 두 개의 Eureka 서버를 구성한다고 가정해 봅시다.
첫 번째 Eureka 서버 (eureka-server-1) 설정:
spring.application.name=eureka-server-1
server.port=8761
eureka.instance.hostname=eureka-server-1
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://eureka-server-2:8762/eureka/
두 번째 Eureka 서버 (eureka-server-2) 설정:
spring.application.name=eureka-server-2
server.port=8762
eureka.instance.hostname=eureka-server-2
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://eureka-server-1:8761/eureka/
이 설정을 통해 두 Eureka 서버는 서로를 피어로 인식하고 정보를 동기화합니다.
4.2 클라이언트 설정 변경
클라이언트 애플리케이션에서는 모든 Eureka 서버의 주소를 지정해야 합니다:
eureka.client.service-url.defaultZone=http://eureka-server-1:8761/eureka/,http://eureka-server-2:8762/eureka/
이렇게 설정하면 클라이언트는 두 Eureka 서버 중 하나가 다운되어도 다른 서버를 통해 서비스 디스커버리를 계속할 수 있습니다.
5. Eureka의 자가 보호 모드
Eureka는 네트워크 문제나 기타 이슈로 인해 등록된 인스턴스들과의 통신이 어려워질 때 "자가 보호 모드(Self-Preservation Mode)"로 전환됩니다. 이 모드에서 Eureka는 등록된 인스턴스들의 정보를 계속 유지하며, 일시적인 네트워크 문제로 인해 서비스가 제거되는 것을 방지합니다.
5.1 자가 보호 모드의 작동 원리
- Eureka 서버는 클라이언트로부터 주기적으로 하트비트를 받습니다.
- 일정 시간 동안 예상된 하트비트의 수보다 적은 수의 하트비트를 받으면 자가 보호 모드로 전환됩니다.
- 자가 보호 모드에서는 인스턴스 등록 정보를 삭제하지 않고 유지합니다.
- 네트워크 상태가 정상화되면 자동으로 일반 모드로 복귀합니다.