"모든 서비스가 자신의 위치(IP, Port)를 등록하고 다른 서비스가 찾을 수 있게 해주는 중앙 등록소"
- 넷플릭스가 개발하고 Spring Cloud에 기여한 오픈소스 서비스 디스커버리 도구
- 마이크로서비스 환경에서 서비스 인스턴스의 위치 정보를 중앙 집중식으로 관리하며, 동적 서비스 탐색과 상태 모니터링 기능을 제공
[Eureka Server Cluster]
⇅ ⇅
[Service A Instance]
⇅ ⇅
[Service B Instance]
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=10s
spring.application.name=eureka-server
# 스프링 시큐리티 기본 인증 설정
spring.security.user.name=admin
spring.security.user.password=1234
# 활성화할 프로필 설정
spring.profiles.active=peer1
# 유레카 클라이언트 설정
# 자신을 유레카 서버에 등록하지 않음 (서버 모드)
eureka.client.register-with-eureka=false
# 레지스트리 정보를 로컬에 캐싱하지 않음 (서버 모드)
eureka.client.fetch-registry=false
# 유레카 서버 설정
# 서비스 등록 정보 캐시 갱신 주기 (밀리초)
eureka.server.response-cache-update-interval-ms=5000
# 등록된 서비스 중 비정상 서비스 제거 주기 (밀리초)
eureka.server.eviction-interval-timer-in-ms=5000
peer 1
# 서버 포트 설정
server.port=8761
# 유레카 인스턴스 호스트명
eureka.instance.hostname=peer1
# 유레카 서버 URL 설정 (클러스터링)
eureka.client.service-url.defaultZone=http://admin:1234@peer2:8762/eureka/
# 자신을 유레카 서버에 등록 (클러스터링 모드)
eureka.client.register-with-eureka=true
# 레지스트리 정보를 로컬에 캐싱 (클러스터링 모드)
eureka.client.fetch-registry=true
peer2
# 서버 포트 설정
server.port=8762
# 유레카 인스턴스 호스트명
eureka.instance.hostname=peer2
# 유레카 서버 URL 설정 (클러스터링)
eureka.client.service-url.defaultZone=http://admin:1234@peer1:8761/eureka/
# 자신을 유레카 서버에 등록 (클러스터링 모드)
eureka.client.register-with-eureka=true
# 레지스트리 정보를 로컬에 캐싱 (클러스터링 모드)
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://admin:1234@localhost:8761/eureka,http://admin:1234@localhost:8762/eureka
클라이언트는 이 목록에서 하나의 서버를 선택해서 요청을 보냄
첫 번째 요청 → Peer1 (http://localhost:8761)
두 번째 요청 → Peer2 (http://localhost:8762)
세 번째 요청 → 다시 Peer1
---
Peer1이 다운된 경우 → Peer2로 요청 전환
Peer2도 다운된 경우 → 서비스 디스커버리 실패
이 방식은 클라이언트와 유레카 서버 간 트래픽을 분산시켜 부하를 줄이는 데 도움을 줌
@EnableWebSecurity(debug = false)
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable);
http.authorizeHttpRequests(authorizeRequests ->
authorizeRequests.anyRequest().authenticated()
);
http.httpBasic(Customizer.withDefaults());
return http.build();
}
}
모든 요청의 단일 입구. 적절한 서비스로 안내하고, 보안 검사도 담당
[Client]
↓ HTTPS
[API Gateway] : 모든 요청의 단일 진입점
⇅
[Eureka Server]
⇅
[Microservices]
# 서버 포트 설정
server.port=8080
# 애플리케이션 이름 설정 (유레카에 등록될 서비스 이름)
spring.application.name=api-gateway
# 서비스 디스커버리 활성화 (유레카를 통한 서비스 자동 발견)
spring.cloud.gateway.discovery.locator.enabled=true
# 서비스 ID를 소문자로 변환 (URL 경로에서 대소문자 구분 없이 사용)
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
# 유레카 서버 주소 설정 (클러스터링된 두 서버 모두 등록)
eureka.client.service-url.defaultZone=http://admin:1234@localhost:8761/eureka,http://admin:1234@localhost:8762/eureka
# IP 주소 사용 (호스트명 대신)
eureka.instance.prefer-ip-address=true
# 로깅 레벨 설정 (게이트웨이 디버깅용)
logging.level.org.springframework.cloud.gateway=DEBUG
logging.level.reactor.netty=DEBUG
@Configuration
public class RouteLocatorConfig {
@Bean
public RouteLocator myRoute(RouteLocatorBuilder builder) {
return builder.routes()
.route("auth-service", r -> r
.path("/auth/**")
.uri("lb://AUTH-SERVICE"))
.route("blog-service", r -> r
.path("/blog/**")
.uri("lb://BLOG-SERVICE"))
.build();
}
}

예시
GET /auth/login → AUTH-SERVICE/auth/login
POST /blog/posts → BLOG-SERVICE/blog/posts
- 클라이언트 요청 : GET http://localhost:8080/auth/login
- 게이트웨이 라우팅 : /auth/** 경로 매칭 -> AUTH-SERVICE로 라우팅 결정
- Eureka 조회 : 유레카 서버에서 AUTH-SERVICE의 등록된 인스턴스 목록을 가져옴
- 로드 밸런싱 : 인스턴스중 하나를 선택 (예: http://auth-service-instance:8081)
- 요청 전달 : 선택된 인스턴스의 /auth/login 엔드포인트로 요청 전달
유레카 서버 http://localhost:8761 에 접속하면 등록된 서비스들이 확인할 수 있다.
[Client]
│
▼
[API Gateway]
├──▶ [Auth Service] /auth/** (JWT 검증 X)
└──▶ [Blog Service] /blog/** (JWT 검증 O)
▲
│
[Service-to-Service Communication]
│
▼
[Eureka Server]
모든 클라이언트 요청은 반드시 API Gateway를 통과

Eureka를 통한 직접 통신 (Gateway 경유하지 않음)

