[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

 

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments