Eureka Server는 Netflix OSS에서 제공하는 서비스 디스커버리 서버이다.
MSA에서는 각각의 서비스가 독립적으로 배포되기 때문에,
고정된 IP와 포트로 통신하는 것이 불가능하다.
Eureka Server의 역할
요약
Eureka는 MSA 환경에서 서비스 간 동적 통신을 가능하게 만드는 핵심 인프라다.
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
}
spring-boot-starter-web+spring-cloud-starter-netflix-eureka-server를 추가한다.
EurekaServerApplication.java
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
@EnableEurekaServer어노테이션이 반드시 필요하다. (이게 있어야 서버로 동작함)
application.yml
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
client:
register-with-eureka: false # 자기 자신은 등록할 필요 없음
fetch-registry: false # 다른 레지스트리에서 목록 가져올 필요 없음
설명
- register-with-eureka: false
- 자기 자신(Eureka 서버)을 또 Eureka에 등록할 필요 없다.
- fetch-registry: false
- 다른 Eureka 서버에서 등록된 목록을 가져올 필요 없다.
http://localhost:8761로 접속한다.초기 화면 특징
| 포인트 | 이유 |
|---|---|
@EnableEurekaServer 반드시 추가 | 안 넣으면 그냥 웹 서버만 띄워짐 |
| 포트 중복 주의 (8761) | 기존 서비스랑 충돌 가능성 |
| Spring Cloud 버전 호환성 주의 | Spring Boot 3.4.4 기준, 최신 Spring Cloud 2023.x 사용 |
| 등록/탐색 설정 명확히 구분 | (register/fetch 둘 다 false 설정 필요) |
Eureka Server 구축 정리
Eureka Server는 MSA 환경에서 서비스들의 "주소록" 같은 역할을 한다.
이를 통해 서비스들은 동적으로 서로를 찾고 통신할 수 있다.
Config Server는 여러 마이크로서비스의 설정 파일을 중앙 집중식으로 관리하는 서버다.
MSA 환경에서는 수십 개, 수백 개의 서비스가 각각 다른 설정을 필요로 하므로,
각 서비스가 따로 설정 파일을 관리하면 유지보수가 거의 불가능해진다.
Config Server를 사용하면
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-config-server'
}
✨
spring-cloud-config-server의존성만 추가하면 된다.
ConfigServerApplication.java
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
@EnableConfigServer어노테이션이 있어야 Config Server로 동작한다.
application.yml
spring:
profiles:
active: native # native 모드: 로컬 디렉토리에서 설정 읽음
application:
name: config-service
cloud:
config:
server:
native:
search-locations: classpath:/configurations # classpath 안의 configurations 폴더 참조
override-system-properties: false # 시스템 프로퍼티 덮어쓰기 방지
server:
port: 8888
management:
endpoints:
web:
exposure:
include: health,info,env # Actuator로 health, info, env 엔드포인트 노출
endpoint:
health:
show-details: always # health 상태 세부정보 항상 보여주기
logging:
level:
org.springframework.cloud.config.server: INFO
요약
- native 모드로 Git이 아닌 로컬 디렉토리를 사용.
/resources/configurations/폴더 안에 서비스별 설정 파일(application-service.yml)을 관리.- Actuator를 통해 서버 상태를 모니터링할 수 있도록 설정.
Config Server의 search-locations 속성은 설정 파일을 어디서 찾을지 지정합니다. 여기서는 classpath:/configurations를 사용했지만, 프로젝트 구성에 따라 다양한 경로 옵션이 가능합니다:
spring:
cloud:
config:
server:
native:
search-locations:
- classpath:/configurations # JAR 내부 경로
- file:./config # 현재 실행 디렉토리의 config 폴더
- file:/opt/config # 절대 경로
- file:${user.home}/config # 사용자 홈 디렉토리
각 옵션별 특징:
실무 팁: 개발 환경에서는
classpath:/configurations를, 운영 환경에서는 외부 파일 시스템 경로를 사용하는 것이 일반적입니다. 컨테이너 환경(Docker)에서는 볼륨 마운트와 함께 파일 경로를 사용하면 설정 변경이 용이합니다.
src/
└── main/
└── resources/
└── configurations/
├── application.yml
├── user-service.yml
├── auth-service.yml
└── ...
각 서비스별로 설정 파일을 따로 관리한다.
http://localhost:8888/application/defaulthttp://localhost:8888/user-service/defaulthttp://localhost:8888/auth-service/defaultTip:
로컬 설정을 잘못 읽으면 404 오류가 발생한다. 디렉토리 경로와 파일명을 꼭 확인하자.
| 포인트 | 이유 |
|---|---|
native 모드 설정 (active: native) | Git 설정과 혼동하지 말 것 |
| search-locations 경로 정확히 작성 | classpath:/configurations ← 정확하게 써야 함 |
| Actuator 엔드포인트 노출 확인 | 상태 모니터링에 필요 (health, env 등) |
| 로컬 환경과 운영 환경 구분 필요 | 이후 Git 연동으로 전환 고려 |
Config Server 구축 정리
Config Server는 MSA에서 서비스 설정을 통합 관리하고,
native 모드를 통해 빠른 개발 환경 세팅이 가능하다.
(운영 전환 시 Git 연동 권장)
API Gateway는 클라이언트 요청을 받아, 적절한 서비스로 전달하고 응답을 반환하는 유일한 진입점(Entry Point) 역할을 한다.
MSA에서는 수많은 마이크로서비스가 존재하므로,
클라이언트가 직접 각각의 서비스를 호출하게 하면 관리가 불가능하다.
API Gateway가 필요한 이유:
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
}
설명
spring-cloud-starter-gateway: API Gateway 핵심 기능 제공spring-boot-starter-webflux: 비동기 서버 기반 (WebFlux) 필요spring-cloud-starter-netflix-eureka-client: Eureka를 통한 서비스 검색 기능 사용
Spring Cloud Gateway는 비동기, 논블로킹 방식으로 동작하는 API Gateway 서비스입니다. 이런 특성은 Spring WebFlux 기반으로 구현되었기 때문에 가능합니다.
비동기(Asynchronous) 처리
Mono<T>, Flux<T> 타입을 반환하여 리액티브 스트림 지원논블로킹(Non-blocking) I/O
높은 확장성
@Component
public class CustomGlobalFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 비동기 처리
return chain.filter(exchange)
.doOnSuccess(v -> {
// 응답 성공 후 처리
})
.doOnError(e -> {
// 오류 처리
});
}
}
application.yml
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service # Eureka에 등록된 서비스 이름
predicates:
- Path=/user/**
- id: auth-service
uri: lb://auth-service
predicates:
- Path=/auth/**
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
요약
/user/**요청은 user-service로/auth/**요청은 auth-service로lb://는 Load Balancer를 의미하며, Eureka에 등록된 서비스 이름 기준으로 라우팅한다.
[Client]
↓
[API Gateway]
↓
[등록된 서비스 (User, Auth 등)]
http://localhost:8080/user/hellohttp://localhost:8080/auth/loginTip:
Eureka Server 대시보드에서도 Gateway가 api-gateway로 정상 등록되는지 확인할 수 있다.
| 포인트 | 이유 |
|---|---|
| 경로(Path) 패턴 정확히 설정 | 잘못 설정하면 요청이 안 넘어간다 |
| Eureka 등록 필수 | Gateway는 서비스 이름 기반으로 라우팅한다 |
lb:// 프로토콜 사용 | LoadBalancerClient를 통해 Eureka와 통신 |
| webflux 기반 서버 | Gateway는 기본적으로 WebFlux 위에서 동작한다 |
API Gateway 구축 정리
API Gateway는 클라이언트와 각 서비스를 중계하며,
요청 경로를 제어하고 시스템 진입을 일원화하는 핵심 컴포넌트다.
MSA 기본 인프라 구축은 다음 순서로 진행된다.
spring.profiles.active=native) 사용classpath:/configurations 디렉토리에서 설정 파일 제공application-서비스이름.yml 파일 작성@EnableEurekaServer 추가register-with-eureka: false, fetch-registry: false 설정spring-cloud-starter-gateway 사용spring-cloud-starter-netflix-eureka-client 연동lb://서비스이름 사용해 Eureka 기반 라우팅[Client]
↓
[API Gateway] --(Service Discovery)--> [Eureka Server]
↓
[Routed to...]
↓
[User-Service] ← Config from Config Server
[Auth-Service] ← Config from Config Server
...
| 체크 항목 | 설명 |
|---|---|
Config Server native 설정 적용 | Git이 아닌 로컬 디렉토리 사용 (classpath:/configurations) |
| Config Server actuator 노출 설정 | health, info, env 확인 가능해야 함 |
Eureka Server에 @EnableEurekaServer 적용 | 메인 클래스에 붙였는지 확인 |
| Eureka Server 포트 충돌 없음 | 기본 8761 사용, 충돌 여부 확인 |
Gateway lb://서비스이름으로 라우팅 설정 | 경로와 서비스 이름 정확히 매칭 |
| 모든 서비스가 Eureka에 정상 등록 | Eureka 대시보드에서 확인 |
| 모든 서비스가 Config Server에서 설정 로딩 | 서버 부팅 시 Config Server 호출 성공 여부 확인 |
요약
Config Server → Eureka Server → API Gateway → 각 마이크로서비스
이 순서로 인프라를 깔끔하게 연결해야
MSA 기본 뼈대가 제대로 구축된다.
지금까지 구축한 MSA 기본 인프라는 개발/테스트 환경에서는 충분히 잘 동작한다.
하지만 실제 운영(Production) 환경에서는 단순 구축만으로는 부족하다.
즉, 하나라도 서버가 죽으면 전체 시스템이 흔들린다.
그래서 HA (High Availability) 와 Failover 설계를 추가로 고려해야 한다.
방법 요약
service-url에 등록해서 복제(replication)하게 만든다.application.yml 예시 (Eureka Server 1)
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8762/eureka/
application.yml 예시 (Eureka Server 2)
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
즉, 서로를 등록하고, 서비스 목록을 공유(sync)한다.
예시: 서비스에서 설정
spring:
config:
import: configserver:http://config1:8888,http://config2:8888
Config Server가 죽어도 다른 서버로 fallback 가능하게 만든다.
API Gateway도 반드시 다중화하고 부하 분산해야 한다.
| 항목 | 고가용성(HA) 전략 | 비고 |
|---|---|---|
| Eureka Server | 다중 인스턴스 구성 + 상호 복제 설정 | 최소 2대 이상 권장 |
| Config Server | 다중 인스턴스 + Client Failover URI 설정 | 안정성 향상 |
| API Gateway | 다중 인스턴스 + LoadBalancer 앞단 구성 | 필수 구성 |
MSA는 기본 구축 후에도 운영 환경에 맞춘 견고한 아키텍처 설계가 필요하다.
Netflix Eureka는 널리 사용되는 서비스 디스커버리 솔루션이지만, 대안 기술들도 검토해볼 가치가 있습니다.
Consul은 서비스 디스커버리와 함께 분산 구성 관리 기능을 제공합니다.
장점:
컨테이너 오케스트레이션 플랫폼인 Kubernetes를 사용하는 경우, 내장된 서비스 디스커버리 기능을 활용할 수 있습니다.
장점:
Spring Cloud Config Server 외에도 다양한 설정 관리 솔루션이 있습니다.
Vault는 민감한 정보(비밀번호, API 키 등)의 안전한 저장 및 접근 관리에 특화되어 있습니다.
장점:
Apollo는 중국의 Ctrip에서 개발한 분산 설정 관리 시스템으로, 실시간 설정 변경 전파와 강력한 관리 기능을 제공합니다.
장점:
Spring Cloud Gateway 외에도 다양한 API Gateway 솔루션이 있습니다.
Netflix의 Zuul은 Spring 생태계에서 오랫동안 사용되어 온 API Gateway입니다.
특징:
참고: Zuul 1.x는 Netflix에서 더 이상 적극적으로 개발하지 않고 있으며, Spring Cloud Gateway로의 마이그레이션이 권장됩니다.
Kong은 Lua 기반의 확장 가능한 API Gateway입니다.
장점:
MSA 인프라 구축 시 대안 기술을 선택할 때는 다음 기준을 고려하세요:
| 기준 | 설명 |
|---|---|
| 운영 환경 | Kubernetes 환경이라면 K8s 네이티브 솔루션 고려 |
| 팀 역량 | 팀이 이미 익숙한 기술 스택 우선 |
| 확장성 요구 | 대규모 서비스는 더 확장성 높은 솔루션 필요 |
| 보안 요구사항 | 금융/의료 등 보안이 중요한 도메인은 Vault 같은 솔루션 고려 |
| 생태계 연동 | 기존 모니터링/로깅 시스템과의 통합 용이성 |
이번 실습에서는 단순히 서비스를 쪼개는 것만으로는 MSA가 완성되지 않는다는 것을 체감했다.
Config Server, Eureka Server, API Gateway라는 인프라 서버들이 있어야
진짜로 서비스들이 "제대로 연결되고 관리"될 수 있다는 것을 명확히 이해했다.
핵심 배운 점 3가지
classpath:/configurations) → 애초에 서버가 안 떠버림MSA를 구축하는 것은 생각보다 단순한 작업이 아니다.
기본 인프라 서버를 준비하는 것부터
서비스 간 통신, 장애 대비 구조까지 전부 설계해야
비로소 "운영 가능한" 시스템이 된다는 것을 배웠다.
또한,
이번 실습을 통해 Spring Cloud의 편리함을 느끼면서도,
"편리함" 이면에 숨어 있는 "구조적 복잡성"도 분명히 존재한다는 것을 경험했다.
요약
MSA는 단순히 기술을 배우는 게 아니라,
서비스를 어떻게 관리하고 연결할지에 대한 깊은 고민이 필요한 아키텍처다.