이 글을 읽기 전에 Reactor 모델 등장 배경을 설명하는 https://ghkdqhrbals.github.io/portfolios/docs/Java/5 를 보고 오시면 이해에 도움이 될 것입니다!
본 포스팅은 아래의 Reference들을 번역하고 재정리한 글입니다.
Reference
- https://www.alibabacloud.com/blog/essential-technologies-for-java-developers-io-and-netty_597367
- https://medium.com/geekculture/a-tour-of-netty-5020ecee5494
1. Netty 란?
1.1 Netty Architecture
네티는 JVM 위에서 돌아가는 Reactor I/O 프레임워크입니다.
이전 Reactor Model 에서 설명한 Master-slave Reactor 모델과 비슷하지만 조금 다른데요. 이제부터 알아보겠습니다.

보시면 크게 Boss Group, Worker Group, Executor Group 이 세 가지 그룹으로 나뉘는 것이 보이죠?
Master-slave Reactor 모델과 매칭시켜보면
- Boss Group->Event Loop = Main Reactor
- Worker Group->Event Loop = Sub Reactor
- Executor Group = Thread Pool
위와 같이 매칭됩니다. 조금은 다르겠지만요.
순서를 볼까요?
1.2 Netty 동작 순서
- 클라이언트 요청
- Boss Group 은 클라이언트와 connection 요청을 establish 및 NioSocketChannel 를 만듭니다.
- 그리고 Boss Group 은 자신의 Event Loop 를 돌리면서 모든 NioSocketChannel 를 Worker Group 의 Nio Event Group 이 관리하는 selector에 등록시키죠.
- Worker Group 의 Event Loop 는 계속 돌고 있습니다. 얘는 자신의 selector 에 연결된 채널들에 이벤트를 계속 Push 해주는 역할을 수행하죠. 즉, 자신의 큐에 저장된 네트워크 Inbound 이벤트를 빼서 NioSocketChannel 에 Push 하게 됩니다.
- NioSocketChannel 에서 이벤트를 수신하면, ChannelPipeline 에 들어갑니다.
- ChannelPipeline 은 여러개의 ChannelHandler가 ChannelContext에 의해 linking 되어있습니다. Inbound 이벤트는 소켓을 읽어주는
ChannelInboundHandler가 얘를 인터셉트해서 Task를 수행하게 됩니다. - 이 때, Executor Group의 Thread Pool 에서 스레드를 빼와서 Task를 수행하게 됩니다.
- 이후, 클라이언트에게 요청을 반환하기 위한
ChannelOutboundHandler가 호출되고 소켓 Write를 하게 됩니다.
종합하면 Boss Group 은 Worker Group 내 여러 이벤트 루프들에게 계속해서 이벤트를 쏴주고, 이벤트 루프는 하나의 selector을 이용해서 여러 채널과 여러 핸들러를 운영합니다. 그리고 핸들러들은 read/write 만 담당하며 실제 로직은 Executor Group의 Thread Pool 과 연결되어 수행되게 됩니다. Master-slave Reactor 모델과 매우 유사하죠?
1.3 Netty 장점
이를 통해 만약 특정 클라이언트 요청에 사용되는 비즈니스 로직이 오래걸려도, 다른 요청들은 blocking 되지 않죠! 왜냐하면 Handler는 단순히 read/write 만을 담당하기 때문이죠. 즉, 1. I/O 와 비즈니스 로직을 분리시킨 모델입니다. 또한 2. I/O 가 시간이 오래 걸려도, 다른 Channel 에게 영향을 주지 않게 되죠. 예로 네트워크 Read/Write 와 파일 Read/Write 는 서로 분리된 채널(채널 별 Thread 할당) 이기 때문에, 파일 I/O가 시간이 오래 걸려도 네트워크 I/O에는 영향을 주지 않죠.
다시한번 종합하면, Netty는 비동기 non-blocking에 최적화된 모델이라고 볼 수 있겠습니다!

1.4 Netty Component Details
1.4.1 Channel
네티의 채널은 NIO 의 채널과 동일하게 read/write을 수행하는 컴포넌트입니다. ChannelPipeline 는 여러개의 ChannelHandler 로 이루어져 있으며, ChannelHandler 는 양방향 linked list 로 연결되어 있습니다. Inbound/Outbound 이벤트들은 ChannelPipeline 를 거쳐서 맞는 ChannelHandler 로 흐르게 되죠. 하나의 Channel은 하나의 ChannelPipeline 과 연결되어 있습니다. ChannelHandler 은 이벤트를 Read/Write 하는 역할을 수행합니다. 그리고 실제 비즈니스 로직들은 Executor Group 의 스레드풀에서 스레드 하나 가져와 처리됩니다.
Channel is a component providing users a ways to process I/O operations, such as read and write. A ChannelPipeline encapsulates a series of ChannelHandler instances as two-way linked list. Inbound and outbound events that flow through a channel can be intercepted by the ChannelPipeline. Whenever a channel is created, a ChannelPipeline is created and permanently bound to the channel. Triggered events can be intercepted, passed, ignored or terminated by ChannelHandler. The head of the linked list is HeadContext, and the tail of the linked list is TailContext.
1.4.2 ChannelHandlers
얘도 마찬가지로 NIO 의 Handler와 동일해요. 조금 다른점은 PipeLine 내 여러개가 ChannelHandlerContext 에 의해 양방향 linking 된다는 점이죠.
ChannelHandlers Handles or intercepts events and forwards it to the next handler in a ChannelPipeline. Based on its origin, an event is handled by the ChannelInboundHandler or ChannelOutboundHandler, and the ChannelHandlerContext forwards the event to the next ChannelHandler.
1.4.3 Netty NioEventLoopGroup
얘는 하나의 NIO selector, 하나의 큐, 하나의 스레드로 동작합니다. 이벤트들을 큐에 넣고 관리를 하면서 채널에 계속 엮어주는 역할을 수행하죠.
NioEventLoopGroup contains multiple NioEventLoops and manages their lifecycles. Each NioEventLoop contains an NIO selector, a queue, and a thread. The thread is used to poll the read and write events of the channels registered to the selector and handle the events that are delivered to the queue.
Before reading this post, it will help to read https://ghkdqhrbals.github.io/portfolios/docs/Java/5, which explains why the Reactor model appeared.
This post translates and reorganizes the references below.
Reference
- https://www.alibabacloud.com/blog/essential-technologies-for-java-developers-io-and-netty_597367
- https://medium.com/geekculture/a-tour-of-netty-5020ecee5494
1. What is Netty?
1.1 Netty Architecture
Netty is a Reactor I/O framework that runs on the JVM.
It is similar to the Master-slave Reactor model explained in the previous Reactor Model, but slightly different. Let us look at it now.

As you can see, it is broadly divided into three groups: Boss Group, Worker Group, and Executor Group.
If we match it with the Master-slave Reactor model:
- Boss Group -> Event Loop = Main Reactor
- Worker Group -> Event Loop = Sub Reactor
- Executor Group = Thread Pool
It maps roughly like this, although it is not exactly the same.
Now let us look at the sequence.
1.2 Netty execution sequence
- Client request
- Boss Group establishes the connection request with the client and creates a
NioSocketChannel. - Boss Group runs its Event Loop and registers all
NioSocketChannels to the selector managed by the Worker Group’s Nio Event Group. - The Worker Group’s Event Loop keeps running. It continuously pushes events to the channels connected to its selector. In other words, it pulls network inbound events from its queue and pushes them to
NioSocketChannel. - When
NioSocketChannelreceives an event, it enters theChannelPipeline. - The
ChannelPipelinehas severalChannelHandlers linked byChannelContext. For an inbound event, theChannelInboundHandlerthat reads the socket intercepts it and performs the task. - At this point, a thread is taken from the Executor Group’s thread pool to perform the task.
- After that, the
ChannelOutboundHandleris called to return the response to the client, and socket write is performed.
In summary, Boss Group continuously sends events to several event loops inside Worker Group. Each event loop operates multiple channels and handlers with one selector. The handlers only handle read/write, and the actual logic is executed by connecting to the Executor Group’s thread pool. It is very similar to the Master-slave Reactor model.
1.3 Netty advantages
Through this, even if business logic used by a specific client request takes a long time, other requests are not blocked. That is because the Handler only handles read/write. In other words, it is 1. a model that separates I/O and business logic. Also, 2. even if one I/O operation takes a long time, it does not affect other channels. For example, network read/write and file read/write are separated into different channels, each with its own thread assignment. So even if file I/O takes a long time, it does not affect network I/O.
To summarize again, Netty can be seen as a model optimized for asynchronous non-blocking behavior.

1.4 Netty Component Details
1.4.1 Channel
A Netty channel, like an NIO channel, is a component that performs read/write. ChannelPipeline consists of several ChannelHandlers, and ChannelHandlers are connected as a doubly linked list. Inbound and outbound events flow through the ChannelPipeline to the appropriate ChannelHandler. One Channel is connected to one ChannelPipeline. ChannelHandler handles event read/write. The actual business logic is processed by taking a thread from the Executor Group’s thread pool.
Channel is a component providing users a ways to process I/O operations, such as read and write. A ChannelPipeline encapsulates a series of ChannelHandler instances as two-way linked list. Inbound and outbound events that flow through a channel can be intercepted by the ChannelPipeline. Whenever a channel is created, a ChannelPipeline is created and permanently bound to the channel. Triggered events can be intercepted, passed, ignored or terminated by ChannelHandler. The head of the linked list is HeadContext, and the tail of the linked list is TailContext.
1.4.2 ChannelHandlers
This is also similar to NIO’s Handler. The slight difference is that multiple handlers inside a Pipeline are linked bidirectionally by ChannelHandlerContext.
ChannelHandlers Handles or intercepts events and forwards it to the next handler in a ChannelPipeline. Based on its origin, an event is handled by the ChannelInboundHandler or ChannelOutboundHandler, and the ChannelHandlerContext forwards the event to the next ChannelHandler.
1.4.3 Netty NioEventLoopGroup
This operates with one NIO selector, one queue, and one thread. It puts events into the queue, manages them, and continuously connects them to channels.
NioEventLoopGroup contains multiple NioEventLoops and manages their lifecycles. Each NioEventLoop contains an NIO selector, a queue, and a thread. The thread is used to poll the read and write events of the channels registered to the selector and handle the events that are delivered to the queue.