서비스 디스커버리 는 MSA 구조에서 필수적인 기능으로, 수많은 마이크로서비스가 서로를 동적으로 탐색하고 통신할 수 있도록 해준다.
MSA 구조에서는 수많은 서비스가 독립적으로 동작하며, 네트워크를 통해 서로 통신해야 한다.
이때 고정된 IP나 포트를 사용하는 대신, 각 서비스가 자신을 등록하고 서로를 동적으로 탐색할 수 있도록 하는 메커니즘이 필요하다.
Spring Cloud에서 제공하는 Eureka는 이런 서비스 디스커버리를 가능하게 해주는 대표적인 도구다.
1. Eureka 구성 요소
- Eureka Server: 서비스 레지스트리 역할. 모든 서비스가 여기에 자신을 등록하거나 다른 서비스를 조회한다.
- Eureka Client: 마이크로서비스 애플리케이션. 실행 시 Eureka Server에 자신을 등록하고, 다른 서비스 정보를 조회한다.
2. Eureka Server 설정
의존성 추가 (discovery-server/build.gradle.kts)
dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-server")
}
애플리케이션 설정 (application.yml)
server:
port: 8761
spring:
application:
name: discovery-server
eureka:
client:
register-with-eureka: false
fetch-registry: false
서버 어플리케이션 클래스
@SpringBootApplication
@EnableEurekaServer
class DiscoveryServerApplication
fun main(args: Array<String>) {
runApplication<DiscoveryServerApplication>(*args)
}
3. 클라이언트 서비스 설정
모든 마이크로서비스는 Eureka Client로 동작하게 설정한다.
의존성 추가 (예: user-service/build.gradle.kts)
dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")
}
application.yml 설정
spring:
application:
name: user-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
서비스 실행 후 http://localhost:8761 에 접속하면, 각 마이크로서비스가 정상적으로 등록된 것을 확인할 수 있다.

4. Gateway와 Eureka 통합
Gateway 서비스 역시 Eureka Client로 등록되며, 라우팅 시 URI를 lb://서비스이름
형태로 사용한다.
이는 로드밸런싱과 디스커버리를 동시에 처리할 수 있게 해준다.
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
5. 서비스 간 통신 예시
user-service
에서 auth-service
의 기능을 호출하려면 Eureka를 통해 서비스 이름으로 직접 접근할 수 있다.
@RestController
class TestController(private val restTemplate: RestTemplate) {
@GetMapping("/test-auth")
fun testAuth(@RequestHeader("Authorization") authorization: String): ResponseEntity<String> {
val headers = HttpHeaders()
headers.set("Authorization", authorization)
val entity = HttpEntity<String>(headers)
val response = restTemplate.exchange(
"http://auth-service/hello",
HttpMethod.GET,
entity,
String::class.java
)
return response
}
}
RestTemplate이나 WebClient를 사용할 때도 load-balanced 빈을 설정하면 Eureka에서 인스턴스를 찾아 자동으로 호출해준다.
@Configuration
class RestTemplateConfig {
@LoadBalanced
@Bean
fun restTemplate(builder: RestTemplateBuilder): RestTemplate =
builder.build()
}
6. 테스트결과

[Postman]
│
▼
[Gateway (8080)] --(Eureka로 user-service 인스턴스 조회)-->
│
▼
[user-service] --(Eureka로 auth-service 인스턴스 조회)-->
│
▼
[auth-service] (토큰 검증 후 응답)
│
▼
[user-service]
│
▼
[Gateway]
│
▼
[Postman]
Postman → Gateway → user-service → auth-service
이 모든 과정에서 Eureka가 서비스 위치를 동적으로 연결해주고,
Gateway가 API 진입점 역할을 하며,JWT 인증이 end-to-end로 일관되게 적용된 것을 확인 할 수 있다.
유연한 서비스 탐색의 핵심, Eureka
Eureka는 MSA에서 필수적인 서비스 디스커버리 기능을 안정적으로 제공한다.
고정된 주소에 의존하지 않고 서비스 이름 기반으로 연결되므로, 유연하고 탄력적인 아키텍처를 설계할 수 있다.
다음 포스트에서는 Config Server를 활용해 서비스별 설정을 중앙에서 통합 관리하는 방법을 정리할 예정이다.
이전편 보기
API 라우팅 – Spring Cloud Gateway로 인증/비인증 API 라우팅
참고
자세한 코드는 아래 저장소에서 확인 가능하다.
Github – 저장소