Netty & EventLoop

Spring WebFlux๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‚ด์žฅ ์„œ๋ฒ„๋กœ Netty๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

  • Netty๋Š” ๊ณ ์„ฑ๋Šฅ ๋„คํŠธ์›Œํฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•œ ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ

  • WebFlux๊ฐ€ ์ง€ํ–ฅํ•˜๋Š” ๋…ผ๋ธ”๋กœํ‚น(Non-Blocking) I/O ๋ชจ๋ธ์„ ๊ฐ€์žฅ ํšจ์œจ์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ํ•ต์‹ฌ ๊ธฐ์ˆ 

Netty

  • ๋„คํŠธ์›Œํฌ ํ”„๋ ˆ์ž„์›Œํฌ: TCP/UDP ์†Œ์ผ“๊ณผ ๊ฐ™์€ ์ €์ˆ˜์ค€(low-level) ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ถ”์ƒํ™”ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ ๊ฐ€๋Šฅ

  • ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ฐ ๋น„๋™๊ธฐ: ๋ชจ๋“  I/O ์ž‘์—…(์—ฐ๊ฒฐ ์ˆ˜๋ฆฝ, ๋ฐ์ดํ„ฐ ์ˆ˜์‹  ๋“ฑ)์„ ์ด๋ฒคํŠธ๋กœ ๊ฐ„์ฃผ

    • ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ์ฝœ๋ฐฑ์„ ํ†ตํ•ด ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘

    • ์ด๋กœ ์ธํ•ด ์ž‘์—…์ด ์ง„ํ–‰๋˜๋Š” ๋™์•ˆ ์Šค๋ ˆ๋“œ ์ฐจ๋‹จ ์—†์ด ๋‹ค๋ฅธ ์ž‘์—… ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ

์ ์€ ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋กœ ์ˆ˜๋งŽ์€ ๋™์‹œ ์—ฐ๊ฒฐ์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” Netty์˜ ํŠน์„ฑ์€ WebFlux์˜ ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ชจ๋ธ๊ณผ ์™„๋ฒฝํ•˜๊ฒŒ ๋ถ€ํ•ฉํ•˜์—ฌ ๋‚ด์žฅ ์„œ๋ฒ„๋กœ ์ฑ„ํƒ๋˜์—ˆ๋‹ค.

์ด๋ฒคํŠธ ๋ฃจํ”„ ๊ธฐ๋ฐ˜์˜ ๋น„๋™๊ธฐ ๋™์ž‘ ์›๋ฆฌ

Netty์˜ ํ•ต์‹ฌ์€ ์ด๋ฒคํŠธ ๋ฃจํ”„(Event Loop) ๋ชจ๋ธ๋กœ, ์„ฑ๋Šฅ์˜ ํ•ต์‹ฌ ์—ญํ• ์„ ํ•œ๋‹ค.

  • ์ด๋ฒคํŠธ ๋ฃจํ”„(Event Loop)

    • ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉด์„œ ์ž์‹ ์—๊ฒŒ ํ• ๋‹น๋œ ์ฑ„๋„(Channel, ํด๋ผ์ด์–ธํŠธ์™€์˜ ์—ฐ๊ฒฐ)์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ์Šค๋ ˆ๋“œ ํ• ๋‹น

    • Netty ์„œ๋ฒ„๋Š” ๋ณดํ†ต CPU ์ฝ”์–ด ์ˆ˜์— ๋งž์ถฐ ์†Œ์ˆ˜์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉ

    • ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์ฑ„๋„์„ ๋‹ด๋‹นํ•˜๋ฉฐ, ํ•ด๋‹น ์ฑ„๋„๋“ค์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ

  • ๋™์ž‘ ๊ณผ์ •

    1. ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ์ž์‹ ์—๊ฒŒ ํ• ๋‹น๋œ ์ฑ„๋„๋“ค์„ ๊ณ„์†ํ•ด์„œ ํ™•์ธํ•˜๋ฉฐ ์ด๋ฒคํŠธ ๋ฐœ์ƒ์„ ๊ฐ์‹œ

    2. ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด(์˜ˆ: ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ์ˆ˜์‹ ), ์ด๋ฒคํŠธ ํ(Task Queue)์— ํ•ด๋‹น ์ž‘์—…์„ ๋“ฑ๋ก

    3. ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ํ์—์„œ ์ž‘์—…์„ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด ๋“ฑ๋ก๋œ ํ•ธ๋“ค๋Ÿฌ(Handler, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•œ ๋กœ์ง)๋ฅผ ์‹คํ–‰

    4. ํ•ธ๋“ค๋Ÿฌ์˜ ์‹คํ–‰์€ ๋งค์šฐ ์งง์€ ์‹œ๊ฐ„ ์•ˆ์— ๋๋‚˜์•ผ ํ•˜๋ฉฐ, ์ ˆ๋Œ€ ๋ธ”๋กœํ‚น(Blocking) ์ž‘์—…์„ ํฌํ•จํ•ด์„œ๋Š” ์•ˆ ๋จ

    5. ์ž‘์—… ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚˜๋ฉด ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ๋‹ค์‹œ ์ฑ„๋„๋“ค์„ ๊ฐ์‹œํ•˜๋Š” ์ƒํƒœ๋กœ ๋ณต๊ท€

  • ํ•ต์‹ฌ ์›์น™

    • ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ๊ฐ€ ์ˆ˜๋งŽ์€ ์—ฐ๊ฒฐ์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋งŒ์•ฝ ํ•˜๋‚˜์˜ ์ž‘์—…์—์„œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฉˆ์ถ”๋ฉด(block) ํ•ด๋‹น ์Šค๋ ˆ๋“œ์— ํ• ๋‹น๋œ ๋‹ค๋ฅธ ๋ชจ๋“  ์—ฐ๊ฒฐ์˜ ์ž‘์—… ์ฒ˜๋ฆฌ๋„ ๋ธ”๋กœํ‚น

    • ๋•Œ๋ฌธ์— ๋ธ”๋กœํ‚น ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์„ ๋•Œ subscribeOn(Schedulers.boundedElastic())์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…์„ ์ด๋ฒคํŠธ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”

Netty์˜ ์Šค๋ ˆ๋“œ ๊ตฌ์กฐ

์‹ค์ œ Netty๋Š” ์Šค๋ ˆ๋“œ๋ณ„๋กœ ์—ญํ• ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ํšจ์œจ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•œ๋‹ค.

  • Boss ๊ทธ๋ฃน

    • ๋ณดํ†ต ๋‹จ์ผ ์Šค๋ ˆ๋“œ๋กœ ๊ตฌ์„ฑ

    • ์˜ค์ง ์„œ๋ฒ„ ํฌํŠธ๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์˜ ์ƒˆ๋กœ์šด ์—ฐ๊ฒฐ ์š”์ฒญ์„ ์ˆ˜๋ฝ(accept)ํ•˜๋Š” ์—ญํ• ๋งŒ ๋‹ด๋‹น

    • ์ƒˆ๋กœ์šด ์—ฐ๊ฒฐ์ด ์ˆ˜๋ฆฝ๋˜๋ฉด, ํ•ด๋‹น ์—ฐ๊ฒฐ(์ฑ„๋„)์„ Worker ๊ทธ๋ฃน์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„ ์ค‘ ํ•˜๋‚˜์— ๋“ฑ๋กํ•˜๊ณ  ์ž์‹ ์€ ์ฆ‰์‹œ ๋‹ค์Œ ์—ฐ๊ฒฐ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ๋Œ€๊ธฐ

  • Worker ๊ทธ๋ฃน

    • CPU ์ฝ”์–ด ์ˆ˜์— ๋งž์ถฐ ์ƒ์„ฑ๋œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ๋กœ ๊ตฌ์„ฑ

    • Boss ๊ทธ๋ฃน์œผ๋กœ๋ถ€ํ„ฐ ๋„˜๊ฒจ๋ฐ›์€ ์ฑ„๋„์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  I/O ์ด๋ฒคํŠธ(๋ฐ์ดํ„ฐ ์ฝ๊ธฐ, ์“ฐ๊ธฐ ๋“ฑ) ์ฒ˜๋ฆฌ

    • ์‹ค์งˆ์ ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์™€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์‹คํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ

์ด๋Ÿฌํ•œ ๊ตฌ์กฐ ๋•๋ถ„์— ์—ฐ๊ฒฐ ์ˆ˜๋ฝ๊ณผ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด, ๊ฐ์ž์˜ ์—ญํ• ์—๋งŒ ์ง‘์ค‘ํ•จ์œผ๋กœ์จ ์‹œ์Šคํ…œ ์ „์ฒด์˜ ์„ฑ๋Šฅ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ชจ๋ธ์˜ ๋ณ‘๋ชฉ ์ง€์ ๊ณผ ๊ณผ๋ถ€ํ•˜ ๊ด€๋ฆฌ

๋…ผ๋ธ”๋กœํ‚น ๋ชจ๋ธ์€ ๋ธ”๋กœํ‚น ๋ชจ๋ธ์˜ ์Šค๋ ˆ๋“œ ๊ณ ๊ฐˆ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, ๋ณ‘๋ชฉ ์ง€์ ์ด ์Šค๋ ˆ๋“œ ํ’€์˜ ํฌ๊ธฐ์—์„œ CPU์™€ ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์‹œ์Šคํ…œ ์ž์›์œผ๋กœ ์ „ํ™˜๋  ๋ฟ์ด๋‹ค.

๋ณ‘๋ชฉ ํŒจ๋Ÿฌ๋‹ค์ž„์˜ ์ „ํ™˜

  • ๋ธ”๋กœํ‚น ๋ชจ๋ธ (Thread-per-Request)

    • ํ•œ๊ณ„์ : ๋™์‹œ ์š”์ฒญ ์ˆ˜๊ฐ€ ์Šค๋ ˆ๋“œ ํ’€์˜ ๊ฐ€์šฉ ์Šค๋ ˆ๋“œ ์ˆ˜์— ์˜ํ•ด ๋ฌผ๋ฆฌ์ ์œผ๋กœ ์ œํ•œ

    • ๋ณ‘๋ชฉ ํ˜„์ƒ

      • I/O ๋Œ€๊ธฐ ์ƒํƒœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฆ๊ฐ€ํ•˜๋ฉด์„œ ์ž์›(ํŠนํžˆ ๋ฉ”๋ชจ๋ฆฌ)์€ ์†Œ๋ชจ๋˜์ง€๋งŒ, ์‹ค์ œ ์ž‘์—…์€ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์Œ

      • ๊ฐ€์šฉ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ ๊ฐˆ๋˜๋ฉด ์ƒˆ๋กœ์šด ์š”์ฒญ์€ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฑฐ๋ถ€๋˜๊ฑฐ๋‚˜ ์žฅ์‹œ๊ฐ„ ๋Œ€๊ธฐ

  • ๋…ผ๋ธ”๋กœํ‚น ๋ชจ๋ธ (Event Loop)

    • ํ•œ๊ณ„์ : ์‹œ์Šคํ…œ์˜ CPU ์—ฐ์‚ฐ ๋Šฅ๋ ฅ๊ณผ ๊ฐ€์šฉ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•œ๊ณ„์ ์œผ๋กœ ์ž‘์šฉ

    • ๋ณ‘๋ชฉ ํ˜„์ƒ

      • CPU ๋ถ€ํ•˜: ์‹œ์Šคํ…œ์˜ ์ฒ˜๋ฆฌ ์šฉ๋Ÿ‰์„ ์ดˆ๊ณผํ•˜๋Š” ์š”์ฒญ์ด ์œ ์ž…๋˜๋ฉด, ์ด๋ฒคํŠธ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ์˜ CPU ์‚ฌ์šฉ๋ฅ ์ด ์ฆ๊ฐ€ํ•˜๋ฉด์„œ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์ „๋ฐ˜์ ์œผ๋กœ ์ฆ๊ฐ€

      • ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ: ์ฒ˜๋ฆฌ ์†๋„๋ณด๋‹ค ์œ ์ž… ์†๋„๊ฐ€ ๋น ๋ฅผ ๊ฒฝ์šฐ, ์ฒ˜๋ฆฌ ๋Œ€๊ธฐ ์ค‘์ธ ์š”์ฒญ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์ง€์†์ ์œผ๋กœ ๋ˆ„์ ๋˜๋ฉด์„œ OutOfMemoryError๋ฅผ ์œ ๋ฐœ

๊ณผ๋ถ€ํ•˜ ๊ด€๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜

Spring WebFlux์˜ ๊ทผ๊ฐ„์„ ์ด๋ฃจ๋Š” Netty๋Š” ๊ณผ๋ถ€ํ•˜๋กœ๋ถ€ํ„ฐ ์‹œ์Šคํ…œ์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์ธต์ ์ธ ๋ฐฉ์–ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๊ฐ–์ถ”๊ณ  ์žˆ๋‹ค.

  • Backpressure(๋ฐฐ์••)

    • ๋ฆฌ์•กํ‹ฐ๋ธŒ ์ŠคํŠธ๋ฆผ์˜ ํ•ต์‹ฌ ์›์น™์œผ๋กœ, ์†Œ๋น„์ž๊ฐ€ ์ž์‹ ์˜ ์ฒ˜๋ฆฌ ์šฉ๋Ÿ‰์— ๋งž์ถฐ ์ƒ์‚ฐ์ž์˜ ๋ฐ์ดํ„ฐ ์ƒ์‚ฐ ์†๋„๋ฅผ ์ œ์–ดํ•˜๋Š” ํ”ผ๋“œ๋ฐฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜

    • ๋„คํŠธ์›Œํฌ ๋ ˆ๋ฒจ์—์„œ๋Š” TCP ํ๋ฆ„ ์ œ์–ด๊ฐ€ ์ด ์—ญํ• ์„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ˆ˜ํ–‰

      • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด TCP ์ˆ˜์‹  ๋ฒ„ํผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์†Œ๋น„ํ•˜๋Š” ์†๋„๊ฐ€ ๋А๋ ค์ง€๋ฉด, ๋ฒ„ํผ๊ฐ€ ์ฑ„์›Œ์ง€๊ณ  TCP ์œˆ๋„์šฐ(Window) ํฌ๊ธฐ๊ฐ€ ๊ฐ์†Œ

      • ์ด๋Š” ์†ก์‹  ์ธก(ํด๋ผ์ด์–ธํŠธ)์˜ ์ „์†ก ์†๋„๋ฅผ ๊ฐ์†Œ์‹œ์ผœ ์‹œ์Šคํ…œ์˜ ์ฒ˜๋ฆฌ ์†๋„์™€ ์œ ์ž… ์†๋„๋ฅผ ๋™๊ธฐํ™”

Last updated

Was this helpful?