[Spring Cloud] - 6. Eureka를 이용한 서비스 검색

MSA로 설계된 웹 애플리케이션은 그 인스턴스가 서비스별로 나누어져 있고, 만약 이를 로드 밸런싱을 이용해 여러 서비스를 분산 처리하게 된다면, 서로 다른 인스턴스가 여러 개 생기게 되며, 그렇게 되면 API 요청마다 적절한 인스턴스의 Endpoint를 매겨줘야 합니다. 

Service Discovery는 이러한 문제를 해결하고자, Server-Client 방식과 유사한 Self-Registration Pattern을 이용해 자신의 서비스를 중앙의 Registry에 등록하고, 이를 요청할 때마다 알맞는 Endpoint를 매칭해준다는 것을 알았습니다.

 

Eureka

Spring Cloud 스택에서 이러한 역할을 하는 대표적인 모듈로 Eureka가 있습니다. Eureka는 Netflix OSS 중 하나로 Spring Boot와 호환되어 동작합니다.

Eureka는 기본적으로 REST 기반의 서비스입니다. 따라서 서비스 인스턴스들은 정해진 Eureka Server의 Endpoint를 이용하여 자신을 등록하고, 클라이언트가 원하는 서비스 API에 맞게 서버에서 인스턴스를 매칭시켜주게 됩니다. 

이 외에도 Apache Zookeeper, Consul 등 다양한 Service Discovery를 지원하는 모듈이 있습니다.

 

Create Eureka Server

그럼 이제 간단히 사용 방법에 대해 알아보겠습니다. 먼저 Eureka 서버를 하나 만들어보도록 하죠.

...

extra["springCloudVersion"] = "Hoxton.SR1"

dependencies {
    ...
    implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-server")
    ...
}

dependencyManagement {
    imports {
        mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
    }
}

...

Gradle에 위와 같이 eureka-server dependency를 추가해줍니다. 

# bootstrap.yml
server:
  port: 8761

spring:
  application:
    name: nk-eureka

#  profiles:
#    active: local

eureka:
  client:
    register-with-eureka: true
    fetch-registry: false

그런 다음, resources/bootstrap.yml 파일을 하나 생성하여 위의 내용을 입력해줍니다. 우리는 8761번 포트를 사용할 것이고, 자신의 서비스를 Eureka 서버로 등록할 것입니다. 

그리고, Profiles의 active를 적어넣은 코드를 주석 처리만 하였는데, 이는 Eureka Server의 설정을 Configuration Server와 동기화 했을 때 사용하는 옵션이지만, 현재는 사용하지 않을 것이고, 가능하면 이를 권장하는 바입니다.

왜냐하면, Eureka 서버에 Configuration Server의 정보가 들어가게 되고, 차후에는 Configuration Server에 Eureka Client가 들어가게 됩니다. 그러나 둘 중 어느 한 쪽의 서버가 먼저 실행됐으면 실행되었을지 연정, 두 서버가 동시에 실행되는 경우는 절대 존재하지 않습니다.

따라서 이렇게 되면 두 서버가 서로 내 정보를 가지고 있는 서버를 찾지 못해 실행하지 못하는 상황이 됩니다.

@EnableEurekaServer
@SpringBootApplication
...

마지막으로 EnableEurekaServer라는 어노테이션만 붙여주면 Eureka 서버의 기본 틀이 완성됩니다.

그럼 한 번 실행해보도록 하죠. 

서버를 실행한 뒤, http://localhost:8761에 접속하면, 위와 같이 Eureka의 메인 화면이 나타납니다. 그리고, Eureka 서버에 등록된 클라이언트들은 Instances currently registered with Eureka에 표시되지만, 현재는 아직 Client에서 서버에 등록한 서비스 인스턴스가 없기 때문에 하나도 나오고 있지 않는 모습입니다.

 

Register Instance

그럼 이제 서버가 만들어졌으니, 인스턴스를 등록해보도록 하겠습니다. 먼저 기존 포스트에서 작성한 Member Service를 열어보도록 하겠습니다.

implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")

Gradle 파일을 열고, 디펜던시에 위의 Eureka Client를 추가해줍니다.

eureka:
  client:
    service-url:
      defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}

  instance:
    prefer-ip-address: true

그런 후, Bootstrap.yml 파일을 열고, 위와 같이 Eureka 서버의 URI 주소를 넣어줍니다. 그리고, 가능한 prefer-ip-address 옵션을 true로 설정하여, 클라이언트가 도메인 주소가 아닌 가급적 IP 주소로 통신할 수 있도록 해주는 걸 권장합니다.

@EnableDiscoveryClient
@SpringBootApplication
...

그리고, EnableDiscoveryClient 어노테이션을 추가하고, 서버를 실행하면, Eureka 서버에 member service가 등록됩니다.

확인하기 전에 우리가 한 가지 더 서버에 등록해야 할 것이 있습니다. 바로 API Gateway인데요. 왜 API Gateway도 Eureka 서버에 등록해야 할까요?

API Gateway의 역할은 알다시피 특정 서비스가 있는 엔드포인트를 서비스별로 호출해주는 프록시 역할입니다. 따라서 원하는 API 엔드포인트를 부르게 되면, 게이트웨이는 Eureka 서버를 통해 해당 엔드포인트가 어느 주소에 있는지를 요청하게 되고, Eurka 서버가 이를 제공할 것이기 때문에 Zuul Gateway에서 이를 유연하게 처리할 수 있게 됩니다.

그러면 이제 Zuul Gateway 프로젝트를 열어서, 위와 같이 디펜던시를 추가하고, Eureka 서버를 추가하는 작업을 동일하게 진행합니다.

그리고 다시 Eureka 메인 페이지에 접속하면, 위 이미지처럼 게이트웨이와 Member Service가 Eureka 서버에 등록됩니다.

 

마치며...

여기까지 Eureka를 이용한 Service Discovery에 대해 알아봤습니다. 간단한 인스턴스만을 다루며 테스트만 해보는 것을 다뤄봤습니다만 실제로 영향 있는 테스트를 진행하려면, Docker 등을 이용해서 여러 개 인스턴스를 생성하고, Eureka에 직접 추가하고, 부하 테스트를 진행하는 것이 가장 바람직할 것이라고 봅니다.

기회가 된다면, 부하 테스트 툴을 이용하여 직접 연계 서비스를 한 번 포스팅 해보도록 하겠습니다.

comments powered by Disqus

Tistory Comments 0