
들어가기 전
이 글은 학교 프로젝트에서 사용한 Spring Boot의 Eureka 사용 방법에 대한 내용이다. 강의에서 들은 내용과 독학으로 공부한 내용을 정리한 것이기 때문에 틀린 부분이 있을 수도 있다는 것을 유념하며 읽으면 좋을 거 같다.
Eureka란?
먼저 이름에서 알 수 있다시피 Spring Cloud의 일종이다. Spring Cloud란 Spring Boot를 기반으로 MSA(MicroService Architecture)구축에 특화된 라이브러리들의 집합이라고 할 수 있다. 여기에는 Netflix OSS(Open Soucre Software)가 일부 포함되어 있는데 이들이 바로 Eureka, Hystrix, Zuul, Ribbon 등이다. 이번 글에서는 이 중 Eureka에 대해 알아보자.
Eureka Server/Client
Eureka는 Eureka Server, Eureka Client로 나뉘어진다. Eureka Server는 Eureka Client에 해당되는 서비스들의 상태 정보가 등록되어 있는 서비스이다. 그리고 Eureka Client는 server를 제외하고 MSA를 구성하고 있는 나머지 기능들을 말한다. 예를 들어 gateway나 사용자가 구현한 각 기능들이 client가 되는 것이다.
이렇게 Server와 Client가 나뉜 상태로 어떻게 동작을 하는지 알아보면, 먼저 Eureka Server가 있으면 Client가 처음에 실행될 때 Server에 자신에 대한 정보를 등록을 한다. 이후 30초에 한 번씩 ping을 보내 자기가 살아있음을 알리고 90초 동안 ping을 받지 못하면 server는 client가 사용 불가능한 상태로 판단하고 자신의 client목록에서 해당 서비스를 삭제한다.

이 사진이 Eureka를 적용했을 때 전체적인 REST API 요청의 흐름이다. 먼저 프론트에서 API요청을 보내면 API Gateway에서 해당 요청을 받아 Eureka Server에게 해당 요청을 어떤 Client에게 요청하면 되는지 알아내고 해당 서비스에게 요청을 보낸 뒤 결과를 받아 다시 프론트로 보내는 형식으로 동작을 하게 됩니다.
Eureka Server 만들기
그럼 개념적인 부분은 알아봤으니 이제 코드를 통해 어떻게 만들면 되고 작동하는지 알아보겠습니다.
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
먼저 당연히 의존성에 eureka에 관련된 라이브러리들을 추가해줘야 합니다. 이 프로젝트는 eureka server역할을 하기 때문에 하나의 라이브러리만 추가해도 됩니다.
그러고 나선 application.properties 파일에서 환경설정을 해줘야하는데 여기서는 서버로 사용될 포트 번호, 해당 application의 이름, 기타 설정 사항들이 들어간다.
server.port=8761
spring.application.name=discoveryservice
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
아래 두 줄의 코드는 eureka server 자체는 본인이 관리하는 서비스 목록에 포함시키지 않는다라는 것이다. 기본값은 true이므로 false로 해주자 물론 그대로 둬도 별 상관은 없다.
그리고 나선 그냥 java파일을 만들어 main문을 만들어 주기만 하면 된다. 물론 적절한 어노테이션을 붙여야 하는 건 당연하다.
package com.javaproject.eurekaserver;
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);
}
}
위 코드를 보면 기본적으로 springboot인걸 말해주는 springBootApplication 어노테이션과 eureka server임을 알려주는 enableEurekaServer 어노테이션이 달려있는 걸 볼 수 있다. 해당 어노테이션들을 붙이고 나면 따로 할 건 없다. 그냥 다른 프로젝트들과 같이 main문을 실행만 하면 된다.
그러게 실행을 하고 나면

해당 포트로 접속을 해보면 이렇게 spring eureka server 실행화면이 나온다. 현재는 등록된 서비스가 없어 사용가능한 인스턴스가 없다고 나오지만 서비스를 등록하면 목록에 추가된다. 그럼 이제 eureka client를 등록할 차례이다.
Eureka Client 만들기
server도 만들었으니 이제는 client를 만들 차례이다. client로는 보통 gateway와 프로젝트에 포함된 백엔드 기능들을 등록한다. 이 프로젝트에서는 gateway와 게시판 기능을 담당하는 post, 회원가입과 로그인을 담당하는 user 총 3개의 프로젝트를 등록할 예정이다.
먼저 gateway를 만들어보자. 사실 Eureka Client를 만드는 방식도 Server를 만드는 방식과 비슷하다. 기본적으로 각 기능들이 필요한 라이브러리를 추가하고 eureka-client 라이브러리만 추가하면 끝이다.
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
보다시피 이 프로젝트는 gateway를 담당하기 때문에 gateway 라이브러리를 추가하고 그 다음으로 eureka-client 라이브러리를 추가한 걸 볼 수 있다.
이제 환경설정을 담당하는 파일을 만들면 되는데 gateway의 경우 여기서 라우팅을 하기 때문에 설정할 것들이 좀 많아진다.
# application.yml
server:
port: 8000
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: apigateway-service
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: [ "*" ]
allowedHeaders: [ "*" ]
routes:
- id: user-service
predicates:
- Path=/api/users/**
uri: lb://USER-SERVICE
- id: post-service
predicates:
- Path=/api/posts/**
uri: lb://POST-SERVICE
- id: post-image-service
predicates:
- Path=/static/**
uri: lb://POST-SERVICE
가장 먼저 역시 gateway가 실행될 포트번호를 설정한다. 여기서는 8000번이다. 그런 다음 해당 서비스를 server에 등록하기 위해서 server의 주소를 등록한다. 여기서는 eureka.client.service-url.defaultZone으로 설정한 주소이다.
그런 다음 이제 route를 등록하면 되는데 그전에 cors 설정을 해준다. 현재 코드는 요청을 보낸 곳이 어디든지 해당 요청을 처리하는 것으로 되어 있는데 이건 본인의 프로젝트에 따라 달라질거기 때문에 넘어간다(본인은 어차피 개인 프로젝트이고 로컬에서 실행하는 것이기 때문에 이렇게 해놓은 것이다). 이제 중요한 routes 부분인데 먼저 각 서비스별로 설정해야 하는 건 id, predicates, path, url 정도이다. id는 서비스의 이름을 뜻하는 것인데 이건 각 서비스의 환경 설정을 할때 정한 application.name과 동일하게 설정해야 한다. 그런 다음 predicate.path를 설정하는데 이 부분이 바로 요청 url에 따라서 각 서비스로 요청을 분산하는 부분이다.
즉 /api/users로 시작하는 요청이 들어오면 gateway가 해당 요청을 user-service에게 보내서 요청을 처리한다는 것이다. 여기선 uri 부분이 요청을 처리할 서비스를 뜻한다.
마지막으로 server와 같이 이 spring boot를 실행하기 위한 main문을 만들면 끝이다.
package com.javaproject.eurekagateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekagatewayApplication {
public static void main(String[] args) {
SpringApplication.run(EurekagatewayApplication.class, args);
}
}
단 여기서는 EnableDiscoveryClient 어노테이션을 사용하여 해당 프로젝트가 client임을 나타내고 있다. 즉 해당 어노테이션있어야 이 프로젝트가 실행될때 server로 등록을 요청하는 것이다.
이제 gateway까지 만들었으니 예시가 될 서비스를 하나 더 만들면 된다.
이 서비스도 gateway를 만들때와 같다. 먼저 해당 서비스가 사용하는 라이브러리를 모두 추가한뒤 eureka-client 라이브러리만 추가하면 의존성은 준비 완료이다. 그런 다음 환경설정을 하면 되는데 이 부분 역시 db연결등 서비스가 필요한 모든 설정을 하고 eureka server에 등록을 하기위한 설정을 추가하면 된다.
spring.application.name=post-service
eureka.instance.instance-id=${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
이게 server에 등록을 하기위한 설정 부분인데 보다시피 본인의 이름, instance-id 지정, 연결한 eureka server 주소를 설정하면 된다.
그런 다음 역시 마찬가지로 main이 있는 부분에 @EnableDiscoveryClient 어노테이션을 달아서 해당 서비스가 client임을 표시한다.
정리
이렇게 모든 서비스를 Eureka Server에 등록을 하고 나면 MSA로 구축한 프로젝트가 완성이 된다.
이번 글에서 예시로 든 프로젝트는 사실 굉장히 간단한 버전으로 각 클라이언트 간의 연결 그러니까 post 서비스와 user 서비스와의 연결도 안한 버전이다. 실제로는 각 client끼리도 API로 연결을 해서 각 서비스가 서로의 데이터가 필요하면 API를 통해서 데이터를 주고받을 수 있어야 한다. 그리고 처음에 말했듯이 사실 spring cloud에는 zuul이라는 게이트웨이 라이브러리가 따로 있는데 spring boot의 버전이 올라감에 따라서 이제 zuul이 아까 사용한 starter-gateway로 대체되고 있다. 하지만 spring 측에서는 여전히 zuul을 사용하고 있는 경우도 많으므로 둘다 배우기를 권장하고 있다.
'SpringBoot' 카테고리의 다른 글
| [Udemy] Spring Boot 3 - Section 4 : Spring Framework 고급기능 살펴보기 (1) | 2023.11.09 |
|---|---|
| [Udemy] Spring Boot 3 - 의존성 주입 (2) | 2023.11.07 |
| [Udemy] Spring Boot 3 - @Primary VS @Qualifier (1) | 2023.11.02 |
| [Udemy] Spring Boot 3 - Java Bean, POJO, Spring Bean 차이 (6) | 2023.11.01 |
| [Udemy] SpringBoot 3 - Spring Bean (0) | 2023.11.01 |