이 글은 회사 동료와 진행한 32회차 스터디에서 제가 공유한 내용입니다.
틀린 정보가 있을 수 있으니 감안하여 참고 바랍니다.
Netflix에서 공유한 클라우드 오픈소스로,Eureka 라는 이름으로 불립니다.
스트리밍 서비스에서는 서비스의 부하를 분산시키기 위한 로드밸런싱 기술이 필수적입니다. 이를 위해 넷플릭스가 사용한 기술입니다.
모듈의 연결 정보를 자동으로 관리합니다.
서비스 부하가 늘어가면 스케일 아웃을 통해 부하를 분산시키는데, 모듈의 버전업, 그리고 스케일 아웃을 위한 인스턴스를 등록할 때마다 연결 정보를 새로이 관리해야하는 불편함이 있습니다.
그러나 Eureka를 이용한 환경을 구축하게 되면, 모듈의 가동과 함께 연결 정보가 관리되어 더욱 편리하게 모듈 관리를 할 수 있습니다. (MSA에서 효과적인 방법입니다)
큰 그림으로 보면, 다른 서비스를 호출할 때 Eureka 서버를 거쳐 로드밸런서 역할을 합니다.
Eureka는 서비스 모듈들인 Eureka Client와, 이들을 관리하는 Eureka Server가 있습니다.
Eureka Client는 모듈 가동시 EureKa Server에 자신의 정보를 등록합니다.
Eureka Server는 Client의 정보를 확인하고, 주기적인 Health Check를 통해 서비스의 인스턴스 목록을 관리하고, 서비스별로 모듈을 묶어 관리합니다.
Client에 대한 접속정보 관리를 Eureka에서는 Discovery 라고 표현합니다.
결과적으로 사용자 요청 → API Gateway →Eureka Server → API Gateway는 요청할 서비스 인스턴스 정보를 수신, 서비스에 요청 → API Gateway가 서비스 응답을 수신 → 사용자에게 반환
의 구조로 진행합니다.
찍어먹기 프로젝트는 위의 구조로 진행합니다.
위와 같이 멀티 프로젝트로 구성했으나, 특별한 의미는 없습니다.
EurekaClient의 정보를 관리하는 서버이다. localhost:8761 경로로 접속하면 아래의 페이지를 만날 수 있다. (EurekaClient로 등록된 인스턴스들이 목록에 보인다)
사용자의 요청을 받아서 DiscoveryServer에 요청을 전달하는 중간 모듈이다.
/ALPHA-SERVICE
와 /BETA-SERVICE
경로에 따라 서비스 요청을 받으면, 이를 DiscoveryServer에 요청을 전달한다. DiscoveryServer는 로드밸런서 역할을 수행하여 적절한 모듈로 요청을 보낸다.
server:
port: 8000
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: alpha-service
predicates:
- Path=/alpha/**
uri: lb://ALPHA-SERVICE
filters:
- RewritePath=/alpha/(?<segment>.*), /$\{segment}
- id: beta-service
predicates:
- Path=/beta/**
uri: lb://BETA-SERVICE
filters:
- RewritePath=/beta/(?<segment>.*), /$\{segment}
서비스 모듈이다. DiscoveryServer가 EurekaClient를 관리할 때는 spring.application.name
으로 묶어서 서비스를 관리하고, 각각 인스턴스는 eureka.instance.instance-id
로 관리한다.
server:
port: 0 # 매번 포트 번호를 랜덤으로 생성
spring:
application:
name: alpha-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka # Eureka Server 명시
instance:
# instance-id를 구분지어주지 않으면 instance UP(1)로 고정됨
instance-id: ${spring.application.name}(${random.uuid})
lease-renewal-interval-in-seconds: 30 # 서버로 heartbeat를 보내는 주기. 기본 값 : 30 (초)
lease-expiration-duration-in-seconds: 90 # heartbeat가 수신되지 않으면 eureka 서버에서 인스턴스 제거 기본 값 : 90 (초)
여러 인스턴스를 띄우는 상황을 가정하기 위해, Run/Debug Configurations에서 Allow multiple instances
를 허용한다.
http://localhost:8000/alpha/check
로 요청을 보내서, 응답하는 AlphaService의 인스턴스가 달라지는 것을 확인할 수 있다.
설정 값에 대한 설명이 있어 실제 활용할 때 참고하기 좋은 링크입니다.
예제를 참고하여 진행했습니다.