[Spring Cloud] - 4. Zuul Gateway를 이용한 Routing

지난 MSA 포스트에 이어, 이번 포스트에서는 Spring Cloud에서 API Gateway를 구현해보겠습니다.

https://blog.neonkid.xyz/205

 

[MSA] - 2. API Gateway가 필요한 이유

안녕하세요. 이번 글은 MSA에 대한 글을 이어서 API Gateway에 대한 이야기를 하고자 합니다. 지난 MSA 글에서는 MSA를 왜 써야하는지, 어떨 때 필요하고, 무슨 장단점이 있는지를 간략하게 설명해보는 아주 쉬운..

blog.neonkid.xyz

혹시 지난 글을 읽어보시지 못했다면, 위 링크를 통해서 API Gateway가 MSA에서 왜 필요한지, 알아보시고 가신다면, 이 포스트를 이해하는 데 도움이 될 것이라고 생각합니다.

 

Gateway for Spring Cloud

Spring Cloud에서 Gateway는 현재 아래의 5개의 항목을 제공하고 있습니다.

여기서 다룰 것은 Zuul인데요. Zuul 외에도 여러 게이트웨이가 있지만, 대표적으로 Spring 프로젝트 생성시 나타나는 선택지는 위의 5가지 입니다. 그 외에도 Linkerd, nginx (legacy) 등 여러가지가 있죠.

 

Zuul Gateway

Zuul Gateway는 Netflix에서 개발한 오픈 소스 게이트웨이 중 하나로, 실제로 Zuul은 Netflix에서 아래와 같이 사용되고 있습니다.

Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application. As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security. It also has the ability to route requests to multiple Amazon Auto Scaling Groups as appropriate.

Zuul은 Netflix 스트리밍 애플리케이션의 백엔드 웹 사이트와 디바이스 간의 이르는 모든 요청의 앞단으로, Edge Service Application으로써 동적 라우팅, 모니터링, 복원력과 보안을 위해 구축되었습니다. 또한 Amazon Auto Scaling 그룹에 있는 컨테이너들의 요청을 라우팅 할 수 있는 기능을 제공합니다.

이 문구는 Zuul의 Github Wiki에 첫 문구로 기록되어 있는 Zuul의 역할을 간단히 기재한 것입니다. 실제로 백엔드 서비스를 개발할 때 가장 첫 번째로 고려해야 하는 사항은 무자비한 트래픽일 것입니다.

서비스를 한 번 오픈하고, 상당한 사용자들이 접속하게 되는 것은 이제 고급이 아닌 필수가 되었습니다. PC 뿐만 아니라 모바일 디바이스에서도 이제 서버에 접속할 수 있는 시대가 왔기 때문에 다양한 클라이언트들이 접속하고, 멀티미디어 서비스의 경우 텍스트 서비스에 비해 트래픽량이 수 십배 이상이 달하는데, 이를 처리하다보면, 운영에 이슈가 발생하고, 이를 신속하게 처리하기 위해 생겨난 것이 바로 Zuul Gateway 입니다.

 

Routing

이 포스트에서는 Routing에 대해서 이야기하고자 합니다. API를 개발한 다음, 라우팅은 언제 어떻게 사용해야 할까요?

지난 포스트를 복습하는 겸, MSA의 경우, 각 서비스별로 이렇게 API 서버가 다르게 구성되어 있습니다. 하지만 각 포트번호가 다르고, IP 주소가 다르기 때문에 어떤 API가 어느 URI로 되어 있는지 찾기가 어렵습니다.

기존의 모놀리틱 아키텍처는 같은 IP 주소와 포트주소를 사용해 EndPoint만 가지고 쉽게 클라이언트가 호출하면 되었지만, MSA를 사용하게 되면 서로 다른 IP와 포트 주소를 사용하는 탓에 혼동이 올 수가 있죠.

이럴 떄 라우팅 기능을 사용해서, 특정 주소를 정해놓고, 라우팅하도록 하면 엔드포인트만 알고 있어도 쉽게 클라이언트가 접근할 수 있습니다.

 

Create Zuul Gateway

그럼 이제 Spring Cloud에 Zuul Gateway를 직접 한 번 붙여보도록 하죠. 이 포스트에서는 Kotlin과 Gradle을 사용하도록 하겠습니다.

repositories {
    mavenCentral()
    maven { url = uri("https://repo.spring.io/snapshot") }
    maven { url = uri("https://repo.spring.io/milestone") }
}

extra["springCloudVersion"] = "Hoxton.BUILD-SNAPSHOT"

dependencies {
    implementation("org.springframework.boot:spring-boot-starter")
    implementation("org.springframework.cloud:spring-cloud-starter-netflix-zuul")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    }
}

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

build.gradle.kts 파일에 위와 같이 Zuul dependency를 추가해줍니다. 

# application.yml
spring:
  application:
    name: nk-gateway

server:
  port: 9100

zuul:
  routes:
    member:
      stripPrefix: false
      path: /v1/member/**
      url: http://localhost:8080

    note:
      stripPrefix: false
      path: /v1/note/**
      url: http://localhost:8081

    else:
      stripPrefix: false
      path: /v1/**
      url: http://localhost:8081

Zuul Gateway의 애플리케이션 이름과 사용할 포트 주소를 입력해줍니다.

그 다음은 각 API를 호출하였을 때, 라우팅할 원래 URL 주소를 설정해야 합니다. 그래야만 Gateway 주소와 엔드포인트를 호출하였을 때 해당 API URI 주소를 호출하도록 하는 것이죠. 

@EnableZuulProxy
@SpringBootApplication
class GatewayexampleApplication

fun main(args: Array<String>) {
    runApplication<GatewayexampleApplication>(*args)
}

마지막으로 @EnableZuulProxy 어노테이션을 입력하여 Zuul Gateway를 구축하시면 끝입니다.

 

Test

게이트웨이를 만들었으니, 내가 만든 API가 제대로 라우팅되어지는지 확인해보도록 하죠.

그러면 Zuul Gateway가 실행 중인 9100번 주소에서 Member API 엔드포인트를 호출핧 경우, 자동으로 Member 서버로 라우팅 되는 것을 확인할 수 있습니다.

 

마치며...

여기까지 Zuul Gateway를 사용해서 API를 라우팅하는 아주 간단한 내용을 다뤄봤습니다. Zuul Gateway에서 라우팅은 각 서비스 앞단에 구축되어 있어, 클라이언트가 원하는 API를 찾는 데 이정표 역할을 하는 존재입니다. 

다음 파트에서는 Zuul Gateway를 이용한 Filtering에 대해 알아보도록 하겠습니다.

 

Ref: Zuul wiki(https://github.com/Netflix/zuul/wiki

 

comments powered by Disqus

Tistory Comments 0