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๋ฅผ ๋ด์ฅ ์๋ฒ๋ก ์ฌ์ฉํ์ฌ ๋ ผ๋ธ๋กํน ์์คํ ์ผ๋ก ๋์
๋์ ์๋ฆฌ
ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด, Netty์ ์ด๋ฒคํธ ๋ฃจํ ์ค๋ ๋๊ฐ ์์ฒญ ์์
Spring Cloud Gateway์ ์ ์๋ ๋ค์ํ ํํฐ(Filter)์ ๋ผ์ฐํ ๊ท์น(Route)๋ค์ด ์์ฐจ์ ์ผ๋ก ์ ์ฉ(์ธ์ฆ, ๋ก๊น , ํค๋ ๋ณ์กฐ ๋ฑ์ ๊ธฐ๋ฅ์ ์ํ)
๋ชจ๋ ์ฒ๋ฆฌ๋ ๋ฆฌ์กํฐ๋ธ ์คํธ๋ฆผ(Mono, Flux) ํ์ดํ๋ผ์ธ ์์์ ์ฒ๋ฆฌ
๋ผ์ฐํ ๊ท์น์ ๋ฐ๋ผ ๋ ผ๋ธ๋กํน HTTP ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ด๋ถ ๋ง์ดํฌ๋ก์๋น์ค๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ํธ์ถ
๋ด๋ถ ์๋น์ค๋ก๋ถํฐ ์๋ต์ด ์ค๋ฉด, ๋ค์ ๋ฆฌ์กํฐ๋ธ ํ์ดํ๋ผ์ธ์ ํตํด ์๋ต ํํฐ๋ค์ด ์ ์ฉ๋ ํ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌ
์ ์ ์์ ์ค๋ ๋๋ก ๋์ ์ฒ๋ฆฌ๋๊ณผ ํ์ฅ์ฑ์ ํ๋ณดํ๋ ์๋ฆฌ
์ค๋ ๋์ ํจ์จ์ ์ฌ์ฉ: ์ค๋ ๋๊ฐ 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) ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ, ๋์ ์ฒ๋ฆฌ๋๊ณผ ๋ฎ์ ์ง์ฐ ์๊ฐ์ ์ ๊ณตํ๋ค.
ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด,
DispatcherHandler๊ฐ ๊ฐ์ฅ ๋จผ์ ์์ฒญ์ ๋ฐ์์์ฒญ์
RoutePredicateHandlerMapping์ ํตํด ์ด๋คRoute์ ์ผ์นํ๋์ง ๊ฒ์ฌ(Predicate ํ๊ฐ)์ผ์นํ๋
Route๋ฅผ ์ฐพ์ผ๋ฉด, ์์ฒญ์FilteringWebHandler๋ก ์ ๋ฌ๋์ด ํด๋นRoute์ ์ ์๋ ํํฐ ์ฒด์ธ์ ์์ฐจ์ ์ผ๋ก ์คํํํฐ ์ฒด์ธ์ Pre-Filter(์์ฒญ ์ ๋ฌ ์ )์ Post-Filter(์๋ต ๋ฐ์ ํ)๋ก ๋๋์ด ๋์
๋ชจ๋ ํํฐ๋ง์ด ์๋ฃ๋๋ฉด, ์์ฒญ์ ์ค์ ๋ง์ดํฌ๋ก์๋น์ค๋ก ํ๋ก์๋๊ณ , ์๋ต ์ญ์ ํํฐ ์ฒด์ธ์ ์ญ์์ผ๋ก ๊ฑฐ์ณ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌ
๋ฆฌ์กํฐ๋ธ ์คํธ๋ฆผ์ผ๋ก์์ ์์ฒญ ์ฒ๋ฆฌ
Spring Cloud Gateway๋ ์์ฒญ๊ณผ ์๋ต์ ๋จ์ผ ๋ฐ์ดํฐ๊ฐ ์๋, ์ด๋ฒคํธ์ ์ฐ์์ ์ธ ํ๋ฆ, ์ฆ ๋ฆฌ์กํฐ๋ธ ์คํธ๋ฆผ(Reactive Stream)์ผ๋ก ์ฒ๋ฆฌํ๋ค.
์คํธ๋ฆผ ์์ฑ(Publisher ์์ฑ)
ํด๋ผ์ด์ธํธ ์์ฒญ์ด ๋ค์ด์ค๋ฉด, Netty ์๋ฒ๋ ์ด๋ฅผ I/O ์์ ์ด ์ฒ๋ฆฌ๋๋ ์ด๋ฒคํธ ๋ฃจํ(Event Loop)์ ํ ๋น
์์ฒญ์ ์ฆ์ ์ฒ๋ฆฌ๋์ง ์๊ณ ,
ServerHttpRequest๊ฐ์ฒด๋ฅผ ํฌํจํMono<ServerWebExchange>๋ผ๋ ์คํธ๋ฆผ ๊ฐ์ฒด๋ก ํฌ์ฅMono๊ฐ์ฒด๋ "์์ฒญ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง"์ ๋ํ ์ค๊ณ๋(Publisher)์ด๋ฉฐ, ์์ง ์คํ๋์ง ์์ ์ํ
์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ ์ ์(Operator ์ฒด์ด๋)
DispatcherHandler๋ ์ด ์ค๊ณ๋๋ฅผ ๋ฐ์, ์ด๋คRoute๋ก ๋ณด๋ผ์ง ๊ฒฐ์ (Predicateํ๊ฐ)ํด๋น
Route์ ํ์ํ ํํฐ(GatewayFilter,GlobalFilter)๋ค์ ์์๋๋ก ์ฐ๊ฒฐํ์ฌ ํ์ดํ๋ผ์ธ์ ์์ฑ
๊ตฌ๋ ๊ณผ ์คํ(Subscription & Execution)
์ ์๋ ํ์ดํ๋ผ์ธ์ ๋งจ ๋์์
.subscribe()๊ฐ ํธ์ถ๋๋ ์๊ฐ, ์ค์ ๋ฐ์ดํฐ ํ๋ฆ์ด ์์์์ฒญ ๋ฐ์ดํฐ๋ Pre-Filter ์ฒด์ธ์ ์์๋๋ก ํต๊ณผํ ํ, ์ค์ ๋ง์ดํฌ๋ก์๋น์ค๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์ ๋ฌ
์ด๋ ์์ฒญ์ ๋ณด๋ธ ์ค๋ ๋๋ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ๋ฉ์ถ์ง ์๊ณ (Non-Blocking) ์ฆ์ ๋ฐํ๋์ด ๋ค๋ฅธ ์์ฒญ ์ฒ๋ฆฌ
๋น๋๊ธฐ ์๋ต ์ฒ๋ฆฌ(Asynchronous Response)
๋ค์ด์คํธ๋ฆผ ์๋น์ค๋ก๋ถํฐ ์๋ต์ด ์ค๋ฉด, ์ด๋ฒคํธ๋ก ๊ฐ์ฃผ๋์ด ํ์ดํ๋ผ์ธ์ ์ญ๋ฐฉํฅ์ผ๋ก ํ๊ณ ํ๋ฅด๋ฉด์ Post-Filter ๋ก์ง์ด ์ ์ฉ
์๋ต ๋ฐ์ดํฐ๋ Post-Filter ์ฒด์ธ์ ํต๊ณผํ๋ฉฐ ๊ฐ๊ณต๋ ํ, ์ต์ข ์ ์ผ๋ก ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌ
์ด์ฒ๋ผ ๋ชจ๋ ์์ฒญ ์ฒ๋ฆฌ ๊ณผ์ ์ ํ๋์ ๊ฑฐ๋ํ ํ์ดํ๋ผ์ธ(Pipeline)์ ์ ์ํ๋ ๊ฒ๊ณผ ๊ฐ์ผ๋ฉฐ, ์ค์ ๋ฐ์ดํฐ ํ๋ฆ์ ๋ง์ง๋ง์ ๊ตฌ๋ (subscribe)์ด ์ผ์ด๋ ๋ ์์๋๋ค.
Last updated
Was this helpful?