WebFlux in API Gateway

API Gateway์˜ ์ฃผ๋œ ์—ญํ• ์€ ์š”์ฒญ์„ ๋ฐ›์•„์„œ ๋‚ด๋ถ€ ์„œ๋น„์Šค๋กœ '์ „๋‹ฌ'ํ•˜๊ณ , ๊ทธ ์‘๋‹ต์„ ๋‹ค์‹œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ '์ „๋‹ฌ'ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

API Gateway์—์„œ Non-Blocking ๋ฐฉ์‹์ด ์ค‘์š”ํ•œ ์ด์œ 

API Gateway ์ž‘์—… ํŠน์„ฑ์ƒ CPU ์ง‘์•ฝ์ ์ธ ๊ณ„์‚ฐ๋ณด๋‹ค๋Š” ๋Œ€๋ถ€๋ถ„ I/O(๋„คํŠธ์›Œํฌ ์ž…์ถœ๋ ฅ) ์ž‘์—…์— ํ•ด๋‹นํ•œ๋‹ค.

  • I/O Bound ์ž‘์—…์˜ ํŠน์„ฑ

    • ์š”์ฒญ์„ ๋ฐ›๊ณ  ๋‚ด๋ถ€ ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ๊ฒŒ์ดํŠธ์›จ์ด๋Š” ๋‚ด๋ถ€ ์„œ๋น„์Šค๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์ด ์˜ฌ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

    • ๊ธฐ์กด์˜ ๋ธ”๋กœํ‚น(Blocking) ๋ฐฉ์‹์—์„œ๋Š” ์ด '๋Œ€๊ธฐ' ์‹œ๊ฐ„ ๋™์•ˆ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋˜ ์Šค๋ ˆ๋“œ๋Š” ๊ณ„์†ํ•ด์„œ ๋Œ€๊ธฐ

    • ๋งŽ์€ ๋™์‹œ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๊ฒฝ์šฐ, ๋Œ€๊ธฐํ•˜๋Š” ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ๊ธ‰๊ฒฉํžˆ ์ฆ๊ฐ€ํ•˜์—ฌ ๋Œ€๊ทœ๋ชจ ์Šค๋ ˆ๋“œ ํ’€์ด ํ•„์š”

  • Non-Blocking ๋ฐฉ์‹์˜ ์ด์ 

    • WebFlux์™€ ๊ฐ™์€ ๋…ผ๋ธ”๋กœํ‚น ๋ชจ๋ธ์—์„œ๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ๋Œ€๊ธฐํ•˜์ง€ ์•Š์Œ

    • ๋‚ด๋ถ€ ์„œ๋น„์Šค์— ์š”์ฒญ์„ ๋ณด๋‚ธ ์Šค๋ ˆ๋“œ๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ๋‹ค๋ฅธ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Ÿฌ ๋ณต๊ท€

    • ๋‚˜์ค‘์— ๋‚ด๋ถ€ ์„œ๋น„์Šค๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์ด ์˜ค๋ฉด, ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์ด๋ฅผ ๊ฐ์ง€ํ•˜์—ฌ ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ํ›„์† ์ž‘์—… ์ฒ˜๋ฆฌ

    • ์ด๋กœ ์ธํ•ด ์†Œ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋งŒ์œผ๋กœ๋„ ์ˆ˜๋งŽ์€ ๋™์‹œ ์š”์ฒญ์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ

Spring Cloud Gateway์—์„œ์˜ WebFlux

Spring Cloud Gateway๋Š” Spring ์ƒํƒœ๊ณ„์—์„œ MSA๋ฅผ ์œ„ํ•œ API Gateway ์Šคํƒ์œผ๋กœ, Spring WebFlux ์œ„์—์„œ ๊ตฌ์ถ•๋˜์—ˆ๋‹ค.

  • ๊ธฐ์ˆ  ์Šคํƒ: Spring Boot, Spring WebFlux, Project Reactor ๊ธฐ๋ฐ˜์œผ๋กœ, Netty๋ฅผ ๋‚ด์žฅ ์„œ๋ฒ„๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋…ผ๋ธ”๋กœํ‚น ์‹œ์Šคํ…œ์œผ๋กœ ๋™์ž‘

  • ๋™์ž‘ ์›๋ฆฌ

    1. ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด, Netty์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ๊ฐ€ ์š”์ฒญ ์ˆ˜์‹ 

    2. Spring Cloud Gateway์— ์ •์˜๋œ ๋‹ค์–‘ํ•œ ํ•„ํ„ฐ(Filter)์™€ ๋ผ์šฐํŒ… ๊ทœ์น™(Route)๋“ค์ด ์ˆœ์ฐจ์ ์œผ๋กœ ์ ์šฉ(์ธ์ฆ, ๋กœ๊น…, ํ—ค๋” ๋ณ€์กฐ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰)

    3. ๋ชจ๋“  ์ฒ˜๋ฆฌ๋Š” ๋ฆฌ์•กํ‹ฐ๋ธŒ ์ŠคํŠธ๋ฆผ(Mono, Flux) ํŒŒ์ดํ”„๋ผ์ธ ์œ„์—์„œ ์ฒ˜๋ฆฌ

    4. ๋ผ์šฐํŒ… ๊ทœ์น™์— ๋”ฐ๋ผ ๋…ผ๋ธ”๋กœํ‚น HTTP ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด๋ถ€ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ํ˜ธ์ถœ

    5. ๋‚ด๋ถ€ ์„œ๋น„์Šค๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์ด ์˜ค๋ฉด, ๋‹ค์‹œ ๋ฆฌ์•กํ‹ฐ๋ธŒ ํŒŒ์ดํ”„๋ผ์ธ์„ ํ†ตํ•ด ์‘๋‹ต ํ•„ํ„ฐ๋“ค์ด ์ ์šฉ๋œ ํ›„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌ

์ ์€ ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋กœ ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰๊ณผ ํ™•์žฅ์„ฑ์„ ํ™•๋ณดํ•˜๋Š” ์›๋ฆฌ

  • ์Šค๋ ˆ๋“œ์˜ ํšจ์œจ์  ์‚ฌ์šฉ: ์Šค๋ ˆ๋“œ๊ฐ€ I/O ์ž‘์—…์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” idle ์‹œ๊ฐ„์ด ๊ฑฐ์˜ ์—†์–ด, ์Šค๋ ˆ๋“œ๋ฅผ ํ•ญ์ƒ ์‹ค์ œ ์ž‘์—…์„ ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ

  • ๋‚ฎ์€ ์˜ค๋ฒ„ํ—ค๋“œ

    • ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ์ ๊ธฐ ๋•Œ๋ฌธ์— ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ „ํ™˜ํ•˜๋Š” ๋ฐ ๋“œ๋Š” ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋น„์šฉ ๊ฐ์†Œ

    • ์Šค๋ ˆ๋“œ ํ•˜๋‚˜๋‹น ์ฐจ์ง€ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„(Thread Stack)๋„ ์ ˆ์•ฝ๋˜์–ด ์ „์ฒด์ ์ธ ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰ ๊ฐ์†Œ

๋ฆฌ์•กํ‹ฐ๋ธŒ ์ฒด์ธ์œผ๋กœ ๊ตฌํ˜„๋œ ํ•„ํ„ฐ ์‹คํ–‰

๋ธ”๋กœํ‚น ๋ฐฉ์‹์˜ ํ•„ํ„ฐ์™€ ๊ฐ€์žฅ ํฐ ์ฐจ์ด๋ฅผ ๋ณด์ด๋Š” ํ•ต์‹ฌ์œผ๋กœ, ์ „ํ†ต์ ์ธ ํ•„ํ„ฐ๋Š” ๋‹จ์ˆœํžˆ ๋‹ค์Œ ํ•„ํ„ฐ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์ง€๋งŒ, ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ•„ํ„ฐ ์ฒด์ธ์€ Mono์™€ ๊ฐ™์€ ๋ฆฌ์•กํ‹ฐ๋ธŒ ํƒ€์ž…์œผ๋กœ ์—ฐ๊ฒฐ๋œ๋‹ค.

  • ๊ฐ ํ•„ํ„ฐ๋Š” filter(ServerWebExchange exchange, GatewayFilterChain chain) ๋ฉ”์„œ๋“œ ๊ตฌํ˜„

    • ServerWebExchange ๋งค๊ฐœ๋ณ€์ˆ˜: HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต์— ๋Œ€ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ํฌํ•จ

    • chain ๋งค๊ฐœ๋ณ€์ˆ˜: '๋‹ค์Œ ํ•„ํ„ฐ'๋ฅผ ํฌํ•จํ•œ ๋‚˜๋จธ์ง€ ์ฒด์ธ ์ „์ฒด๋ฅผ ์˜๋ฏธ

  • 'Pre' ํ•„ํ„ฐ ๋กœ์ง: chain.filter(exchange)๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์˜ ์ž‘์—…

    • ๋‹ค์šด์ŠคํŠธ๋ฆผ ์„œ๋น„์Šค๋กœ ์š”์ฒญ์ด ์ „๋‹ฌ๋˜๊ธฐ ์ „์— ์‹คํ–‰

    • ์ฃผ๋กœ ์š”์ฒญ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์—ญํ• 

  • 'Post' ํ•„ํ„ฐ ๋กœ์ง: chain.filter(exchange)๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” Mono<Void>์— .then(), flatMap ๊ฐ™์€ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐ๋œ ํ›„์† ์ž‘์—…

    • ๋‹ค์šด์ŠคํŠธ๋ฆผ ์„œ๋น„์Šค๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์ด ๋Œ์•„์˜จ ํ›„์— ์‹คํ–‰

    • ์ฃผ๋กœ ์‘๋‹ต ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‘๋‹ต ๋ณธ๋ฌธ์„ ๋กœ๊น…ํ•˜๋Š” ์—ญํ• 

๋™์ž‘ ๊ณผ์ •

๋™์ž‘ ๊ณผ์ •์€ ๋‚ด๋ถ€์ ์œผ๋กœ Project Reactor์™€ Netty์— ๊ธฐ๋ฐ˜ํ•œ ๋น„๋™๊ธฐ ๋…ผ๋ธ”๋กœํ‚น(Asynchronous Non-Blocking) ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ, ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰๊ณผ ๋‚ฎ์€ ์ง€์—ฐ ์‹œ๊ฐ„์„ ์ œ๊ณตํ•œ๋‹ค.

  1. ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด, DispatcherHandler ๊ฐ€ ๊ฐ€์žฅ ๋จผ์ € ์š”์ฒญ์„ ๋ฐ›์Œ

  2. ์š”์ฒญ์€ RoutePredicateHandlerMapping ์„ ํ†ตํ•ด ์–ด๋–ค Route์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ(Predicate ํ‰๊ฐ€)

  3. ์ผ์น˜ํ•˜๋Š” Route๋ฅผ ์ฐพ์œผ๋ฉด, ์š”์ฒญ์€ FilteringWebHandler ๋กœ ์ „๋‹ฌ๋˜์–ด ํ•ด๋‹น Route์— ์ •์˜๋œ ํ•„ํ„ฐ ์ฒด์ธ์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰

  4. ํ•„ํ„ฐ ์ฒด์ธ์€ Pre-Filter(์š”์ฒญ ์ „๋‹ฌ ์ „)์™€ Post-Filter(์‘๋‹ต ๋ฐ›์€ ํ›„)๋กœ ๋‚˜๋‰˜์–ด ๋™์ž‘

  5. ๋ชจ๋“  ํ•„ํ„ฐ๋ง์ด ์™„๋ฃŒ๋˜๋ฉด, ์š”์ฒญ์€ ์‹ค์ œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋กœ ํ”„๋ก์‹œ๋˜๊ณ , ์‘๋‹ต ์—ญ์‹œ ํ•„ํ„ฐ ์ฒด์ธ์„ ์—ญ์ˆœ์œผ๋กœ ๊ฑฐ์ณ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌ

๋ฆฌ์•กํ‹ฐ๋ธŒ ์ŠคํŠธ๋ฆผ์œผ๋กœ์„œ์˜ ์š”์ฒญ ์ฒ˜๋ฆฌ

Spring Cloud Gateway๋Š” ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋‹จ์ผ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ, ์ด๋ฒคํŠธ์˜ ์—ฐ์†์ ์ธ ํ๋ฆ„, ์ฆ‰ ๋ฆฌ์•กํ‹ฐ๋ธŒ ์ŠคํŠธ๋ฆผ(Reactive Stream)์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.

  1. ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ(Publisher ์ƒ์„ฑ)

    • ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด, Netty ์„œ๋ฒ„๋Š” ์ด๋ฅผ I/O ์ž‘์—…์ด ์ฒ˜๋ฆฌ๋˜๋Š” ์ด๋ฒคํŠธ ๋ฃจํ”„(Event Loop)์— ํ• ๋‹น

    • ์š”์ฒญ์€ ์ฆ‰์‹œ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š๊ณ , ServerHttpRequest ๊ฐ์ฒด๋ฅผ ํฌํ•จํ•œ Mono<ServerWebExchange> ๋ผ๋Š” ์ŠคํŠธ๋ฆผ ๊ฐ์ฒด๋กœ ํฌ์žฅ

      • Mono ๊ฐ์ฒด๋Š” "์š”์ฒญ์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€"์— ๋Œ€ํ•œ ์„ค๊ณ„๋„(Publisher)์ด๋ฉฐ, ์•„์ง ์‹คํ–‰๋˜์ง€ ์•Š์€ ์ƒํƒœ

  2. ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ ์ •์˜(Operator ์ฒด์ด๋‹)

    • DispatcherHandler ๋Š” ์ด ์„ค๊ณ„๋„๋ฅผ ๋ฐ›์•„, ์–ด๋–ค Route๋กœ ๋ณด๋‚ผ์ง€ ๊ฒฐ์ •(Predicate ํ‰๊ฐ€)

    • ํ•ด๋‹น Route์— ํ•„์š”ํ•œ ํ•„ํ„ฐ(GatewayFilter,GlobalFilter)๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ํŒŒ์ดํ”„๋ผ์ธ์„ ์™„์„ฑ

  3. ๊ตฌ๋…๊ณผ ์‹คํ–‰(Subscription & Execution)

    • ์ •์˜๋œ ํŒŒ์ดํ”„๋ผ์ธ์˜ ๋งจ ๋์—์„œ .subscribe() ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์ˆœ๊ฐ„, ์‹ค์ œ ๋ฐ์ดํ„ฐ ํ๋ฆ„์ด ์‹œ์ž‘

    • ์š”์ฒญ ๋ฐ์ดํ„ฐ๋Š” Pre-Filter ์ฒด์ธ์„ ์ˆœ์„œ๋Œ€๋กœ ํ†ต๊ณผํ•œ ํ›„, ์‹ค์ œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋กœ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ „๋‹ฌ

    • ์ด๋•Œ ์š”์ฒญ์„ ๋ณด๋‚ธ ์Šค๋ ˆ๋“œ๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ (Non-Blocking) ์ฆ‰์‹œ ๋ฐ˜ํ™˜๋˜์–ด ๋‹ค๋ฅธ ์š”์ฒญ ์ฒ˜๋ฆฌ

  4. ๋น„๋™๊ธฐ ์‘๋‹ต ์ฒ˜๋ฆฌ(Asynchronous Response)

    • ๋‹ค์šด์ŠคํŠธ๋ฆผ ์„œ๋น„์Šค๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์ด ์˜ค๋ฉด, ์ด๋ฒคํŠธ๋กœ ๊ฐ„์ฃผ๋˜์–ด ํŒŒ์ดํ”„๋ผ์ธ์„ ์—ญ๋ฐฉํ–ฅ์œผ๋กœ ํƒ€๊ณ  ํ๋ฅด๋ฉด์„œ Post-Filter ๋กœ์ง์ด ์ ์šฉ

    • ์‘๋‹ต ๋ฐ์ดํ„ฐ๋Š” Post-Filter ์ฒด์ธ์„ ํ†ต๊ณผํ•˜๋ฉฐ ๊ฐ€๊ณต๋œ ํ›„, ์ตœ์ข…์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌ

์ด์ฒ˜๋Ÿผ ๋ชจ๋“  ์š”์ฒญ ์ฒ˜๋ฆฌ ๊ณผ์ •์€ ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ ํŒŒ์ดํ”„๋ผ์ธ(Pipeline)์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์œผ๋ฉฐ, ์‹ค์ œ ๋ฐ์ดํ„ฐ ํ๋ฆ„์€ ๋งˆ์ง€๋ง‰์— ๊ตฌ๋…(subscribe)์ด ์ผ์–ด๋‚  ๋•Œ ์‹œ์ž‘๋œ๋‹ค.

Last updated

Was this helpful?