Netty
- https://github.com/netty/netty/wiki/User-guide-for-4.x
- https://netty.io/wiki/user-guide-for-4.x.html
- 공식 docs가 최고야!
Netty가 무엇인가?
- Netty is an asynchronous event-driven network application framework.
- Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients.
- It greatly simplifies and streamlines network programming such as TCP and UDP socket server.
Spring WebFlux와 Netty?
- Spring WebFlux는 다음 두 가지 타입의 서버를 지원
- Tomcat 등 Servlet 3.1+ container
- WebFlux 서버로 쓰려면 non-blocking I/O API를 지원해야 함.
- Servlet 3.1, Tomcat 8.5 부터는 NIO API를 지원.
- 그러나 다른 Servlet API는 여전히 동기식, Blocking API라서 애매한 구석이 있음. (docs)
- Netty 등 non-Servlet runtime
- 어느 쪽을 쓰든, 프로그래밍 모델은 고수준으로 추상화 되어 있음.
- Tomcat 등 Servlet 3.1+ container
- SpringBoot의 WebFlux starter는 Netty를 기본 서버로 사용하고 있음.
EventLoopGroup
- NioEventLoopGroup is a multithreaded event loop that handles I/O operation.
- server-side application을 구현한다면 두개의 NioEventLoopGroup 가 사용됨.
- The first one, often called 'boss', accepts an incoming connection.
- 스레드 개수 1로 지정하면 하나만 뜬다. 포트가 여러개 열려도, 하나의 스레드가 여러개의 포트를 listen한다.
- 스레드 개수 2개이고 포트 2개이면 스레드 하나 당 포트 하나를 listen하게 되고.
- The second one, often called 'worker', handles the traffic of the accepted connection once the boss accepts the connection and registers the accepted connection to the worker.
- 주어진 worker 스레드에 accept된 커넥션이 분배된다.
- 16개의 worker 스레드, 160개의 커넥션이라면 한 스레드 당 대략 10개의 커넥션을 맡아 처리하게 된다.
- The first one, often called 'boss', accepts an incoming connection.
- How many Threads are used and how they are mapped to the created Channels depends on the EventLoopGroup implementation and may be even configurable via a constructor.
Persistence Layer가 블로킹이면 어떻게?
- https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-framework-choice
- 위 공식 링크 보면 나온다.
- Persistence API가 JPA, JDBC같은 Blocking API이면 일단 Spring MVC가 Best Choice라고 함.
- 그러나 Reactive로 차근히 전환하고 싶은 상황이라면?
- Persistence API가 Blocking이면 그 앞단에서 Worker Group을 쓴다고 해도, 결국 워커의 수 보다 더 많은 요청이 들어오는 경우 모든 워커가 응답을 대기하며 Blocking에 빠질 수 있다.
- 이렇게 되면 기존 스레드 기반 모델보다 성능이 더 안좋을 수도 있다.
- 그래서, 모든 워커스레드가 블로킹에 빠지지 않도록 뭔가 조치를 취해야 한다.
- 뒤쪽에 EventLoop를 하나 더 만들어서 Blocking job을 여기에 던지는 식으로 처리하는게 한 가지 대안이 될 수 있다.
- gRPC가 이런 방법을 사용한다.
- Persistence API를 코루틴 등으로 래핑해서 비동기처럼 만들어 쓰는 방법도 같은 맥락에서 사용할 수 있다.
- 뒤쪽에 EventLoop를 하나 더 만들어서 Blocking job을 여기에 던지는 식으로 처리하는게 한 가지 대안이 될 수 있다.
- Persistence API가 Blocking이면 그 앞단에서 Worker Group을 쓴다고 해도, 결국 워커의 수 보다 더 많은 요청이 들어오는 경우 모든 워커가 응답을 대기하며 Blocking에 빠질 수 있다.
'Java Stack > Java-async' 카테고리의 다른 글
[Java8] CompletableFuture (0) | 2020.10.13 |
---|---|
Reactive Programming (0) | 2020.02.17 |