Spring WebFlux ๋?
- Spring 5 ๋ถํฐ ๋์ ๋ ๋น๋๊ธฐ/๋ ผ๋ธ๋กํน ์น ํ๋ ์์ํฌ
- Reactive Streams ๊ธฐ๋ฐ, ์ ์ ์ค๋ ๋๋ก ๋ง์ ์์ฒญ ์ฒ๋ฆฌ
-> ๊ธฐ์กด Spring MVC = Blocking I/O
-> WebFlux = Non-Blocking I/O + ์ด๋ฒคํธ ๋ฃจํ
WebFlux ์ ๋ฑ์ฅ ๋ฐฐ๊ฒฝ
- Spring MVC์ ๊ตฌ์กฐ์ ํ๊ณ
- ์์ฒญ 1๊ฑด = ์ค๋ ๋ 1๊ฐ
- I/O ๋๊ธฐ๋์ ์ค๋ ๋ ์ ์
- ํธ๋ํฝ ์ฆ๊ฐ -> ์ค๋ ๋ ๊ณ ๊ฐ -> ์๋ต ์ง์ฐ
- WebFlux์ ํด๊ฒฐ ๋ฐฉ์
- I/O ๋๊ธฐ ์ค ์ค๋ ๋ ๋ฐํ
- ์ด๋ฒคํธ๊ฐ ์ค๋ฉด ๋ค์ ์ด์ด์ ์ฒ๋ฆฌ
- ์ ์ ์ค๋ ๋๋ก ๋์์ฑ ์ฒ๋ฆฌ
WebFlux = CPU๊ฐ ์๋๋ผ I/O ๋๊ธฐ ์๊ฐ์ด ๋ณ๋ชฉ์ธ ์๋น์ค๋ฅผ ์ํ ๋ชจ๋ธ
WebFlux ํต์ฌ ๊ฐ๋
- Reactive Streams
- Publisher : ๋ฐ์ดํฐ ๋ฐํ
- Subscriber : ๋ฐ์ดํฐ ๊ตฌ๋
- Backpressure : ์ฒ๋ฆฌ ๊ฐ๋ฅํ ๋งํผ๋ง ์์ฒญ
- Mono / Flux
- Mono<T> : 0~1 ๊ฑด
- Flux<T> : 0~N ๊ฑด
Mono<User> findUser();
Flux<Order> findOrders();
-> return ๊ฐ ์์ฒด๊ฐ ๋ฏธ๋์ ๋์ฐฉํ ๋ฐ์ดํฐ
- Non-Blocking I/O
- ์์ฒญ ์ฒ๋ฆฌ ์ค๋ ๋ ≠ I/O ์ฒ๋ฆฌ ์ค๋ ๋
- ๋๊ธฐ ์์. ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ฌ๊ฐ
Spring MVC vs WebFlux ๋น๊ต
| ๊ตฌ๋ถ | Spring MVC | WebFlux |
| ํ๋ก๊ทธ๋๋ฐ ๋ชจ๋ธ | ๋๊ธฐ | ๋น๋๊ธฐ |
| I/O | Blocking | Non-Blocking |
| ์ค๋ ๋ ๋ชจ๋ธ | ์์ฒญ๋น 1๊ฐ | ์ด๋ฒคํธ ๋ฃจํ |
| ๋ฐํ ํ์ | ๊ฐ์ฒด | Mono / Flux |
| ํ์ต ๋์ด๋ | ๋ฎ์ | ๋์ |
WebFlux๋ ์ธ์ ์ธ๊น?
- ์ธ๋ถ API ํธ์ถ์ด ๋ง์ ์๋น์ค
- ์คํธ๋ฆฌ๋ฐ (SSE, WebSocket)
- ๋๊ท๋ชจ ํธ๋ํฝ, ๊ณ ๋์์ฑ
- MSA ํ๊ฒฝ์ API Gateway
๊ฐ๋จ ์์
- Controller
@GetMapping("/user/{id}")
public Mono<UserResponse> getUser(@PathVariable Long id){
return userService.findById(id)
.map(UserResponse::from);
}
- Service
public Mono<User> findById(Long id) {
return userRepository.findById(id);
}
- ์๋ฌ ์ฒ๋ฆฌ
return userService.findById(id)
.switchIfEmpty(Mono.error(new NotFoundException()));