Skip to main content Link Menu Expand (external link) Document Search Copy Copied

์ด ๊ธ€์„ ์ฝ๊ธฐ ์ „์— Reactor ๋ชจ๋ธ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ์„ ์„ค๋ช…ํ•˜๋Š” https://ghkdqhrbals.github.io/portfolios/docs/Java/5 ๋ฅผ ๋ณด๊ณ  ์˜ค์‹œ๋ฉด ์ดํ•ด์— ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค!

๋ณธ ํฌ์ŠคํŒ…์€ ์•„๋ž˜์˜ Reference๋“ค์„ ๋ฒˆ์—ญํ•˜๊ณ  ์žฌ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

Reference

1. Netty ๋ž€?

1.1 Netty Architecture

๋„คํ‹ฐ๋Š” JVM ์œ„์—์„œ ๋Œ์•„๊ฐ€๋Š” Reactor I/O ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.

์ด์ „ Reactor Model ์—์„œ ์„ค๋ช…ํ•œ Master-slave Reactor ๋ชจ๋ธ๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ์กฐ๊ธˆ ๋‹ค๋ฅธ๋ฐ์š”. ์ด์ œ๋ถ€ํ„ฐ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

img img

๋ณด์‹œ๋ฉด ํฌ๊ฒŒ 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 ๋™์ž‘ ์ˆœ์„œ

  1. ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ
  2. Boss Group ์€ ํด๋ผ์ด์–ธํŠธ์™€ connection ์š”์ฒญ์„ establish ๋ฐ NioSocketChannel ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  3. ๊ทธ๋ฆฌ๊ณ  Boss Group ์€ ์ž์‹ ์˜ Event Loop ๋ฅผ ๋Œ๋ฆฌ๋ฉด์„œ ๋ชจ๋“  NioSocketChannel ๋ฅผ Worker Group ์˜ Nio Event Group ์ด ๊ด€๋ฆฌํ•˜๋Š” selector์— ๋“ฑ๋ก์‹œํ‚ค์ฃ .
  4. Worker Group ์˜ Event Loop ๋Š” ๊ณ„์† ๋Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์–˜๋Š” ์ž์‹ ์˜ selector ์— ์—ฐ๊ฒฐ๋œ ์ฑ„๋„๋“ค์— ์ด๋ฒคํŠธ๋ฅผ ๊ณ„์† Push ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜์ฃ . ์ฆ‰, ์ž์‹ ์˜ ํ์— ์ €์žฅ๋œ ๋„คํŠธ์›Œํฌ Inbound ์ด๋ฒคํŠธ๋ฅผ ๋นผ์„œ NioSocketChannel ์— Push ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  5. NioSocketChannel ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๋ฉด, ChannelPipeline ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
  6. ChannelPipeline ์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ChannelHandler๊ฐ€ ChannelContext์— ์˜ํ•ด linking ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. Inbound ์ด๋ฒคํŠธ๋Š” ์†Œ์ผ“์„ ์ฝ์–ด์ฃผ๋Š” ChannelInboundHandler ๊ฐ€ ์–˜๋ฅผ ์ธํ„ฐ์…‰ํŠธํ•ด์„œ Task๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  7. ์ด ๋•Œ, Executor Group์˜ Thread Pool ์—์„œ ์Šค๋ ˆ๋“œ๋ฅผ ๋นผ์™€์„œ Task๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  8. ์ดํ›„, ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์š”์ฒญ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ 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์— ์ตœ์ ํ™”๋œ ๋ชจ๋ธ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค!

img

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.