엄범

 

 

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
    • 어느 쪽을 쓰든, 프로그래밍 모델은 고수준으로 추상화 되어 있음.
  • 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개의 커넥션을 맡아 처리하게 된다.
  • 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를 코루틴 등으로 래핑해서 비동기처럼 만들어 쓰는 방법도 같은 맥락에서 사용할 수 있다.

gRPC는 내부적으로 이렇게 쓰고 있다.