SERVER/Node.js

๐Ÿ’ปNode.js์˜ ๋…ผ ๋ธ”๋กœํ‚น IO, ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ, ์ด๋ฒคํŠธ ๋ฃจํ”„

์™„์žโœจ 2022. 6. 29. 02:16

๐Ÿ’ปNode.js์˜ ๋…ผ ๋ธ”๋กœํ‚น IO, ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ, ์ด๋ฒคํŠธ ๋ฃจํ”„

Block IO vs Non-Block IO & Sync vs Async์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

Node.js์˜ ๋ชจ๋“  I/O ๋ฉ”์„œ๋“œ๋Š” ๋…ผ๋ธ”๋กœํ‚น์ธ ๋น„๋™๊ธฐ ๋ฐฉ์‹์„ ์ œ๊ณตํ•˜๊ณ  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋ฐ›๋Š”๋‹ค. ์ผ๋ถ€ ๋ฉ”์„œ๋“œ๋Š” ๊ฐ™์€ ์ž‘์—…์„ ํ•˜๋Š” ๋ธ”๋กœํ‚น ๋ฉ”์„œ๋“œ๋„ ๊ฐ€์ง€๋Š”๋ฐ ์ด๋ฆ„ ๋งˆ์ง€๋ง‰์— Sync๊ฐ€ ๋ถ™๋Š”๋‹ค.

Node.js์˜ non-blocking I/O

Node.js์—์„œ์˜ ๋…ผ๋ธ”๋กœํ‚น I/O ๋ชจ๋ธ์€ ๋ธ”๋กœํ‚น ์ž‘์—…(Input, Output๊ณผ ๊ด€๋ จ๋œ ์ž‘์—… / http, Database CRUD, third party api, filesystem)๋“ค์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ(libuv์˜ ์Šค๋ ˆ๋“œ ํ’€)์—์„œ ์ˆ˜ํ–‰ํ•˜๊ณ , ์ด๋ฅผ ๋น„๋™๊ธฐ ์ฝœ๋ฐฑํ•จ์ˆ˜๋กœ ์ด๋ฒคํŠธ ๋ฃจํ”„์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

Node.js๋Š” ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ์ธ๊ฐ€์š”?

  • ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ : ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์š”์ฒญ๋งŒ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ํ•ด๋‹น ์š”์ฒญ์ด ์ˆ˜ํ–‰๋  ๋•Œ ๋‹ค๋ฅธ ์š”์ฒญ์„ ํ•จ๊ป˜ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†๋‹ค.
  • ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ : ์Šค๋ ˆ๋“œ ํ’€์—์„œ ์‹คํ–‰์˜ ์š”์ฒญ๋งŒํผ ์Šค๋ ˆ๋“œ๋ฅผ ๋งค์นญํ•˜์—ฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

Node.js๋Š” ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ ๋…ผ๋ธ”๋กœํ‚น ๋ชจ๋ธ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋กœ ๋™์ž‘ํ•˜์ง€๋งŒ, ๋น„๋™๊ธฐ I/O ์ž‘์—…์„ ํ†ตํ•ด ์š”์ฒญ๋“ค์„ ์„œ๋กœ ๋ธ”๋กœํ‚นํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

์ฆ‰, ๋™์‹œ์— ๋งŽ์€ ์š”์ฒญ๋“ค์„ ๋น„๋™๊ธฐ๋กœ ์ˆ˜ํ–‰ํ•จ์œผ๋กœ์จ ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ์ผ์ง€๋ผ๋„ ๋…ผ๋ธ”๋กœํ‚น์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Node.js๋Š” ์™„์ „ํ•œ ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ์ธ๊ฐ€์š”?

  • Node.js๊ฐ€ ์™„์ „ํžˆ ์‹ฑ๊ธ€์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹Œ ์ด์œ ๋Š” ์ผ๋ถ€ Blocking ์ž‘์—…๋“ค์€ libuv์˜ ์Šค๋ ˆ๋“œ ํ’€(Thread pool)์—์„œ ์ˆ˜ํ–‰๋˜๋Š”๋ฐ, ์ด ์Šค๋ ˆ๋“œ ํ’€์ด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Node.js

ํ”ํžˆ Node.js๋ฅผ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ๋…ผ ๋ธ”๋กœํ‚น์ด๋ผ๊ณ  ํ•œ๋‹ค. Node.js๋Š” ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋กœ ๋™์ž‘ํ•˜์ง€๋งŒ I/O ์ž‘์—…์ด ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ์ด๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ถ„๋ช… ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋Š” ํ•˜๋‚˜์˜ ์‹คํ–‰ ํ๋ฆ„๋งŒ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  ํŒŒ์ผ ์ฝ๊ธฐ์™€ ๊ฐ™์ด ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š” ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋ฉด ๊ทธ ์ž‘์—…์ด ๋๋‚˜๊ธฐ ์ „์—๋Š” ์•„๋ฌด๊ฒƒ๋„ ํ•  ์ˆ˜ ์—†์–ด์•ผ๋งŒ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Node.js๋Š” ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ์œผ๋กœ ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…๋“ค์„ ๋ธ”๋กœํ‚น ์—†์ด ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ณ  ๊ทธ ๊ธฐ๋ฐ˜์—๋Š” ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์กด์žฌํ•œ๋‹ค.

 

Node.js์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ


๋…ธ๋“œ์˜ ๊ตฌ์กฐ๋Š”

  • libuv๋ž€ C++๋กœ ์ž‘์„ฑ๋œ, Node.js๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋น„๋™๊ธฐ I/O ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • libuv์™€ ๋‹ค๋ฅธ ์ €์ˆ˜์ค€ ๊ธฐ๋Šฅ๋“ค์„ ๋žฉํ•‘ํ•˜๊ณ  ํ‘œ์ถœ์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๋ฐ”์ธ๋”ฉ ์„ธํŠธ(socket, http, ...)
  • V8, ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์œ„ํ•œ ๊ตฌ๊ธ€์ด ๊ฐœ๋ฐœํ•œ JavaScript ์—”์ง„์œผ๋กœ Node.js๊ฐ€ ๋งค์šฐ ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ธ ์ด์œ  ์ค‘ ํ•˜๋‚˜์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. V8์€ ํ˜์‹ ์ ์ธ ์„ค๊ณ„์™€ ์†๋„ ๊ทธ๋ฆฌ๊ณ  ํšจ์œจ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋กœ ๋†’์€ ํ‰๊ฐ€๋ฅผ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ณ ์ˆ˜์ค€ Node.js API๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š” ์ฝ”์–ด JavaScript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

 

์œ„ 4๊ฐ€์ง€๋กœ Node.js์˜ ํ”Œ๋žซํผ์„ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

Libuv ํƒ„์ƒ, Node.js์˜ I/O ์—”์ง„

๊ฐ ์šด์˜์ฒด์ œ๋Š” API์™€ ๊ฐ™์€ ์ด๋ฒคํŠธ ๋””๋ฉ€ํ‹ฐํ”Œ๋ ‰์„œ๋ฅผ ์œ„ํ•œ ์ž์ฒด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ I/O ์ž‘์—…์€ ๋™์ผํ•œ OS ๋‚ด์—์„œ๋„ ๋ฆฌ์†Œ์Šค ์œ ํ˜•์— ๋”ฐ๋ผ ๋งค์šฐ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด Unix์—์„œ ์ผ๋ฐ˜ ํŒŒ์ผ ์‹œ์Šคํ…œ์€ ๋…ผ ๋ธ”๋กœํ‚น ์ž‘์—…์„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋…ผ ๋ธ”๋กœํ‚น ๋™์ž‘์„ ์œ„ํ•ด์„œ๋Š” ์ด๋ฒคํŠธ ๋ฃจํ”„ ์™ธ๋ถ€์— ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์„œ๋กœ ๋‹ค๋ฅธ ์šด์˜์ฒด์ œ ๊ฐ„์˜ ๋ถˆ์ผ์น˜์„ฑ์€ ์ด๋ฒคํŠธ ๋””๋ฉ€ํ‹ฐํ”Œ๋ ‰์„œ๋ฅผ ์œ„ํ•œ ๋ณด๋‹ค ๋†’์€ ๋ ˆ๋ฒจ์˜ ์ถ”์ƒํ™”๋ฅผ ํ•„์š”๋กœ ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐํ•œ ์ด์œ ๋กœ Node.js ์ฝ”์–ด ํŒ€์ด Node.js๋ฅผ ์ฃผ์š” ์šด์˜์ฒด์ œ์—์„œ ํ˜ธํ™˜๋˜๊ฒŒ ํ•ด์ฃผ๋ฉฐ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค ์œ ํ˜•์˜ ๋…ผ ๋ธ”๋กœํ‚น ๋™์ž‘์„ ํ‘œ์ค€ํ™”ํ•˜๊ธฐ ์œ„ํ•ด libuv๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” C๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. Node.js์˜ ๊ตฌ์„ฑ์š”์†Œ ์ค‘์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Libuv๋Š” ๊ธฐ๋ณธ ์‹œ์Šคํ…œ ํ˜ธ์ถœ์„ ์ถ”์ƒํ™”ํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ์ด๋ฒคํŠธ ๋ฃจํ”„์˜ ์ƒ์„ฑ, ์ด๋ฒคํŠธ ํ์˜ ๊ด€๋ฆฌ, ๋น„๋™๊ธฐ I/O ์ž‘์—…์˜ ์‹คํ–‰ ๋ฐ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ์ž‘์—…์„ ํ์— ๋‹ด๊ธฐ ์œ„ํ•œ API๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Libuv ๋™์ž‘

libuv ์—๊ฒŒ ํŒŒ์ผ ์ฝ๊ธฐ์™€ ๊ฐ™์€ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์š”์ฒญํ•˜๋ฉด libuv๋Š” ์ด ์ž‘์—…์„ ์ปค๋„์ด ์ง€์›ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ๋งŒ์•ฝ ์ง€์›ํ•œ๋‹ค๋ฉด libuv๊ฐ€ ๋Œ€์‹  ์ปค๋„์—๊ฒŒ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์š”์ฒญํ–ˆ๋‹ค๊ฐ€ ์‘๋‹ต์ด ์˜ค๋ฉด ๊ทธ ์‘๋‹ต์„ ์šฐ๋ฆฌ์—๊ฒŒ ์ „๋‹ฌํ•ด์ค€๋‹ค.

๋งŒ์•ฝ ์š”์ฒญํ•œ ์ž‘์—…์„ ์ปค๋„์ด ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ? ๋ฐ”๋กœ ์ž์‹ ๋งŒ์˜ ์›Œ์ปค ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ด๊ธด ์Šค๋ ˆ๋“œ ํ’€์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

libuv๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ 4๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€์ง€๋Š” ์Šค๋ ˆ๋“œ ํ’€์„ ์ƒ์„ฑํ•œ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •์œผ๋กœ ์ตœ๋Œ€ 128๊ฐœ๊นŒ์ง€ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๋ฅผ ๋Š˜๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์Šค๋ ˆ๋“œ ํ’€์— ์žˆ๋˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋ฉด libuv๊ฐ€ ์šฐ๋ฆฌ์—๊ฒŒ ์š”์ฒญํ•œ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๊ณ  ์นœ์ ˆํ•˜๊ฒŒ ์•Œ๋ ค์ค€๋‹ค.

 

์ฆ‰, ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • libuv๋Š” ์šด์˜์ฒด์ œ์˜ ์ปค๋„์„ ์ถ”์ƒํ™”ํ•ด์„œ ๋น„๋™๊ธฐ API๋ฅผ ์ง€์›ํ•œ๋‹ค.
  • libuv๋Š” ์ปค๋„์ด ์–ด๋–ค ๋น„๋™๊ธฐ API๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์žˆ๋‹ค.
  • ๋งŒ์•ฝ ์ปค๋„์ด ์ง€์›ํ•˜๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ libuv์—๊ฒŒ ์š”์ฒญํ•˜๋ฉด libuv๋Š” ๋Œ€์‹  ์ปค๋„์—๊ฒŒ ์ด ์ž‘์—…์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์š”์ฒญํ•ด์ค€๋‹ค.
  • ๋งŒ์•ฝ ์ปค๋„์ด ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ libuv์—๊ฒŒ ์š”์ฒญํ•˜๋ฉด livuv๋Š” ๋‚ด๋ถ€์— ๊ฐ€์ง€๊ณ ์žˆ๋Š” ์Šค๋ ˆ๋“œ ํ’€์—๊ฒŒ ์ด ์ž‘์—…์„ ์š”์ฒญํ•ด์ค€๋‹ค.

 

Node.js๋Š” I/O ์ž‘์—…์„ ์ž์‹ ์˜ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ์œ„์ž„ํ•จ์œผ๋กœ์จ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ๋กœ ๋…ผ ๋ธ”๋กœํ‚น I/O๋ฅผ ์ง€์›ํ•œ๋‹ค. ๋‹ค๋ฅด๊ฒŒ ๋งํ•˜๋ฉด Node.js๋Š” I/O ์ž‘์—…์„ libuv์—๊ฒŒ ์œ„์ž„ํ•จ์œผ๋กœ์จ ๋…ผ ๋ธ”๋กœํ‚น I/O๋ฅผ ์ง€์›ํ•˜๊ณ  ๊ทธ ๊ธฐ๋ฐ˜์—๋Š” ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์žˆ๋‹ค.

 

Node.js์—์„œ์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„

  • ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” Node.js๊ฐ€ ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๊ตฌํ˜„์ฒด๋‹ค.
  • ๋™๊ธฐ ์ž‘์—…์ด ์•„๋‹ˆ๋ผ file.readFile('test.txt', callback)๊ณผ ๊ฐ™์€ ๋น„๋™๊ธฐ ์ž‘์—…๋“ค์„ ๋ชจ์•„์„œ ๊ด€๋ฆฌํ•˜๊ณ  ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋„๊ตฌ์ด๋‹ค.

์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” 6๊ฐœ์˜ ํŽ˜์ด์ฆˆ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ํŽ˜์ด์ฆˆ๋ฅผ ๋ผ์šด๋“œ ๋กœ๋นˆ(RR) ๋ฐฉ์‹์œผ๋กœ ์ˆœํšŒํ•œ๋‹ค. ํŽ˜์ด์ฆˆ๋Š” ๊ฐ์ž๋งˆ๋‹ค ํ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , FIFO(First In First Out) ์ˆœ์„œ๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋“ค์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

๋ผ์šด๋“œ ๋กœ๋นˆ ์Šค์ผ€์ค„๋ง

  • ์‹œ๋ถ„ํ•  ์‹œ์Šคํ…œ์„ ์œ„ํ•ด ์„ค๊ณ„๋œ ์„ ์ ํ˜• ์Šค์ผ€์ค„๋ง์˜ ํ•˜๋‚˜๋กœ์„œ, ํ”„๋กœ์„ธ์Šค๋“ค ์‚ฌ์ด์— ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋‘์ง€ ์•Š๊ณ , ์ˆœ์„œ๋Œ€๋กœ ์‹œ๊ฐ„๋‹จ์œ„๋กœ CPU๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ์‹์˜ CPU ์Šค์ผ€์ค„๋ง ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.
  • ์ฆ‰, 6๊ฐœ์˜ ํŽ˜์ด์ฆˆ์— ๋ชจ๋‘ ์ผ์ •ํ•œ ์‹œ๊ฐ„์„ ํ• ๋‹นํ•˜๊ณ  ์ฐจ๋ก€๋Œ€๋กœ ์ˆœํšŒํ•˜๋Š” ์Šค์ผ€์ค„๋ง ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์ด๋ฒคํŠธ ๋ฃจํ”„์˜ "๋‹จ๊ณ„" ์„ค๋ช…

๊ฐ ๋‹จ๊ณ„๋Š” ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ์˜ FIFO ํ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์ด ํ์—๋Š” ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…๋“ค์ด ์ˆœ์„œ๋Œ€๋กœ ๋‹ด๊ฒจ์žˆ๋‹ค. ๊ฐ ๋‹จ๊ณ„๋Š” ์ž์‹ ๋งŒ์˜ ๋ฐฉ๋ฒ•์— ์ œํ•œ์ ์ด๋ฏ€๋กœ ๋ณดํ†ต ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ํ•ด๋‹น ๋‹จ๊ณ„์— ์ง„์ž…ํ•˜๋ฉด ํ•ด๋‹น ๋‹จ๊ณ„์— ํ•œ์ •๋œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ํ๋ฅผ ๋ชจ๋‘ ์†Œ์ง„ํ•˜๊ฑฐ๋‚˜ ์ฝœ๋ฐฑ์˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๊นŒ์ง€ ํ•ด๋‹น ๋‹จ๊ณ„์˜ ํ์—์„œ ์ฝœ๋ฐฑ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ๋ฅผ ๋ชจ๋‘ ์†Œ์ง„ํ•˜๊ฑฐ๋‚˜ ์ฝœ๋ฐฑ ์ œํ•œ์— ์ด๋ฅด๋ฉด ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

 

1. timers Phase

  • setTimeout()๊ณผ setInterval() ๊ฐ™์€ ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด ๋‚ด๋Š” ํƒ€์ด๋จธ๋“ค์„ ๋‹ค๋ฃฌ๋‹ค.
  • Timer Phase๋Š” min-heap์„ ์ด์šฉํ•ด์„œ ํƒ€์ด๋จธ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ์ด ๋•๋ถ„์— ์‹คํ–‰ ์‹œ๊ฐ„์ด ๊ฐ€์žฅ ์ด๋ฅธ ํƒ€์ด๋จธ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

 

2. pending callbacks Phase

  • I/O ์ž‘์—… ๋ธ”๋ก ๋‚ด์˜ ์ฝœ๋ฐฑํ•จ์ˆ˜๋“ค์„ poll๋‹จ๊ณ„์˜ ํ๋กœ ๋„˜๊ฒจ์ค€๋‹ค.
  • ์ด ํŽ˜์ด์ฆˆ๋Š” pending_queue์— ๋‹ด๊ธฐ๋Š” ์ฝœ๋ฐฑ๋“ค์„ ๊ด€๋ฆฌํ•œ๋‹ค. ์ด ํ์— ๋‹ด๊ธฐ๋Š” ์ฝœ๋ฐฑ๋“ค์€ ์ด์ „ ์ด๋ฒคํŠธ ๋ฃจํ”„ ๋ฐ˜๋ณต์—์„œ ์ˆ˜ํ–‰๋˜์ง€ ๋ชปํ–ˆ๋˜ I/O ์ฝœ๋ฐฑ๋“ค์ด๋‹ค.
  • ์‹œ์Šคํ…œ์˜ ์‹คํ–‰ ํ•œ๋„ ์ œํ•œ์— ์˜ํ•ด ํ์— ์Œ“์ธ ๋ชจ๋“  ์ž‘์—…์„ ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋‹ค์Œ ํŽ˜์ด์ฆˆ๋กœ ๋„˜์–ด๊ฐˆ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋•Œ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•˜๊ณ  ๋„˜์–ด๊ฐ„ ์ž‘์—…๋“ค์„ ์Œ“์•„๋†“๊ณ  ์‹คํ–‰ํ•˜๋Š” ํŽ˜์ด์ฆˆ๋‹ค.

 

3. Idle, Prepare Phase

  • ์ด ํŽ˜์ด์ฆˆ๋“ค์€ Node.js์˜ ๋‚ด๋ถ€์ ์ธ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ํŽ˜์ด์ฆˆ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ ๋ณ„๋‹ค๋ฅธ ์„ค๋ช…์ด ์—†๊ณ  ์ฝ”๋“œ์˜ ์ง์ ‘์ ์ธ ์‹คํ–‰์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค.

 

4. poll Phase

  • ์ด ํŽ˜์ด์ฆˆ๋Š” ์ƒˆ๋กœ์šด I/O ์ด๋ฒคํŠธ๋ฅผ ๋‹ค๋ฃจ๋ฉฐ watcher_queue์˜ ์ฝœ๋ฐฑ๋“ค์„ ์‹คํ–‰ํ•œ๋‹ค. watcher_queue์—๋Š” I/O์— ๋Œ€ํ•œ ๊ฑฐ์˜ ๋ชจ๋“  ์ฝœ๋ฐฑ๋“ค์ด ๋‹ด๊ธด๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด setTimeout, setImmediate, close ์ฝœ๋ฐฑ ๋“ฑ์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์ฝœ๋ฐฑ์ด ์—ฌ๊ธฐ์„œ ์‹คํ–‰๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝœ๋ฐฑ๋“ค์ด ์‹คํ–‰๋œ๋‹ค.
    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ธ ํ›„ ๊ฒฐ๊ณผ๊ฐ€ ์™”์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ์ฝœ๋ฐฑ
    • HTTP ์š”์ฒญ์„ ๋ณด๋‚ธ ํ›„ ์‘๋‹ต์ด ์™”์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ์ฝœ๋ฐฑ
    • ํŒŒ์ผ์„ ๋น„๋™๊ธฐ๋กœ ์ฝ๊ณ  ๋‹ค ์ฝ์—ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ์ฝœ๋ฐฑ
  • ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด ๋ฐ”๋กœ ๋‹ค์Œ ํŽ˜์ด์ฆˆ๋กœ ๋„˜์–ด๊ฐ„๋‹ค.
    • ๋งŒ์•ฝ Close Callbacks Phase, Pending Callbacks Phase์—์„œ ์‹คํ–‰ํ•  ์ž‘์—…์ด ์žˆ๋‹ค๋ฉด ๋ฐ”๋กœ ๋‹ค์Œ ํŽ˜์ด์ฆˆ๋กœ ๋„˜์–ด๊ฐ„๋‹ค.
    • ๋งŒ์•ฝ Timer Phase์—์„œ ์ฆ‰์‹œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ด๋จธ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ฐ”๋กœ ๋‹ค์Œ ํŽ˜์ด์ฆˆ๋กœ ๋„˜์–ด๊ฐ„๋‹ค.
    • ๋งŒ์•ฝ Timer Phase์—์„œ ์ฆ‰์‹œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ด๋จธ๋Š” ์—†์ง€๋งŒ n์ดˆ ํ›„์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ด๋จธ๊ฐ€ ์žˆ๋‹ค๋ฉด n์ดˆ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋‹ค์Œ ํŽ˜์ด์ฆˆ๋กœ ๋„˜์–ด๊ฐ„๋‹ค.

 

5. check Phase

  • ์ด ํŽ˜์ด์ฆˆ๋Š” ์˜ค์ง setImmediate์˜ ์ฝœ๋ฐฑ๋งŒ์„ ์œ„ํ•œ ํŽ˜์ด์ฆˆ๋‹ค. setImmediate๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด Check Phase์˜ ํ์— ๋‹ด๊ธฐ๊ณ  Node.js๊ฐ€ Check Phase์— ์ง„์ž…ํ•˜๋ฉด ์ฐจ๋ก€๋Œ€๋กœ ์‹คํ–‰๋œ๋‹ค.
  • ๊ณต์‹ ๋ฌธ์„œ์—์„œ setImmediate์™€ process.nextTick์˜ ์ฐจ์ด์— ์ฃผ๋ชฉํ•˜๊ณ  ์žˆ๋‹ค. ์ •๋ฆฌํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
    • process.nextTick์€ ๊ฐ™์€ ํŽ˜์ด์ฆˆ์—์„œ ํ˜ธ์ถœํ•œ ์ฆ‰์‹œ ์‹คํ–‰๋œ๋‹ค.
    • setImmediate๋Š” ๋‹ค์Œ ํ‹ฑ์—์„œ ์‹คํ–‰๋œ๋‹ค. ์ •ํ™•ํžˆ๋Š” Node.js๊ฐ€ ํ‹ฑ์„ ๊ฑฐ์ณ Check Phase์— ์ง„์ž…ํ•˜๋ฉด ์‹คํ–‰๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ๋™์ž‘๋งŒ ๋ณด๋ฉด process.nextTick์€ ์ฆ‰์‹œ ์‹คํ–‰๋˜๊ณ  setImmediate๋Š” ๋‹ค์Œ ํ‹ฑ์— ์‹คํ–‰๋œ๋‹ค.

 

6. close callbacks Phase

  • socket.on('close', () => {});๊ณผ ๊ฐ™์€ close ์ด๋ฒคํŠธ ํƒ€์ž…์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํŽ˜์ด์ฆˆ๋‹ค. ์ •ํ™•ํ•˜๊ฒŒ๋Š” uv_close()๋ฅผ ๋ถ€๋ฅด๋ฉด์„œ ์ข…๋ฃŒ๋œ ํ•ธ๋“ค๋Ÿฌ์˜ ์ฝœ๋ฐฑ๋“ค์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํŽ˜์ด์ฆˆ๋‹ค.

'SERVER > Node.js' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Block IO vs Non-Block IO & Sync vs Async  (0) 2022.06.28
๐Ÿ’ป webRTC Process  (0) 2022.06.22
๐Ÿ“Œ๋™์‹œ์„ฑ๊ณผ ๋ณ‘๋ ฌ์„ฑ  (0) 2022.06.11
๐Ÿ“ŒObserver Pattern์ด๋ž€?  (0) 2022.05.11
SOA, MSA ์•„ํ‚คํ…์ฒ˜๋ž€?  (0) 2022.05.10