Node.js์ Reactor ํจํด
Node.js์ Reactor ํจํด์ ๋ํด์ ์์๋ด ๋๋ค.
Jun 27, 2024
๋ค์ด๊ฐ๋ฉฐ
Node.js ๋์์ธ ํจํด ๋ฐ์ด๋ธ ์ด๋ผ๋ ์ฑ ์ ์ฝ๊ณ ์์ต๋๋ค.
Node.js๋ฅผ ๊น์ด ์ดํดํ๊ณ ์ถ์ด ์ด ์ฑ ์ ๊ตฌ์ ํ์ง๋ง, ํ๋์ ์ฝ์ง ๋ชปํ๊ณ ์์๋๋ฐ์
๋ธ๋ก๊ทธ๋ฅผ ํตํด ์ฑ ์ด๋ฐ๋ถ์ ๋์ค๋ Node.js์ ๋ฆฌ์กํฐ ํจํด์ ๋ํด ์ด์ผ๊ธฐํด ๋ณด๋ ค ํฉ๋๋ค.
Node.js๋ ์ด๋ป๊ฒ ์๋ํ๋๊ฐ?
I/O๋ ๋๋ฆฌ๋ค.
์ฑ ์์ I/O๋ ์ปดํจํฐ์ ๊ธฐ๋ณธ์ ์ธ ๋์๋ค ์ค์์ ๊ฐ์ฅ ๋๋ฆฌ๋ค๊ณ ํฉ๋๋ค. ๋๋ฆฌ๋ค๋ ๊ฐ๋ ์ด ํ ์๋ฟ์ง ์์ I/O์ ๋ํด ์์๋ดค์ต๋๋ค.
- ์ปดํจํฐ์ I/O
์ปดํจํฐ๊ฐ ์ธ๋ถ ์ธ๊ณ์ ํต์ ํ๋ ๋ฐฉ์์ ์๋ฏธํฉ๋๋ค. ์ปดํจํฐ๋ ์ ๋ ฅ ์ฅ์น๋ฅผ ํตํด ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ ์ถ๋ ฅ ์ฅ์น๋ฅผ ํตํด ์ ๋ณด๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
์ ๋ ฅ ์ฅ์น๋ ํค๋ณด๋, ๋ง์ฐ์ค, ๋ง์ดํฌ, ์นด๋ฉ๋ผ ๋ฑ์ด ์์ผ๋ฉฐ, ์ถ๋ ฅ ์ฅ์น๋ ๋ชจ๋ํฐ, ํ๋ฆฐํฐ, ์คํผ์ปค ๋ฑ์ด ์์ต๋๋ค.
์ด๋ฌํ ์ฅ์น๋ค์ CPU, RAM์ ๋นํด ์๋๊ฐ ๋๋ฆฐ๋ฐ, CPU์ ์๋๋ ๊ธฐ๊ฐํค๋ฅด์ธ (GHz) ๋จ์๋ก ์ธก์ ๋๊ณ , RAM์ ๋๋ ธ์ด(ns) ๋๋ ๋ง์ดํฌ๋ก์ด(ยตs)์ธ๋ฐ ๋ฐํด,
I/O ์์ ์ ์ฌ์ฉ๋๋ ์ ๋ ฅ, ์ถ๋ ฅ ์ฅ์น, ํ๋ ๋๋ผ์ด๋ธ, ๋คํธ์ํฌ ๋ฑ์ ๊ธฐ๋ณธ์ ์ผ๋ก MB/s ๋๋ GB/s ๋จ์๋ก ๋ค์ํ๊ฒ ์ธก์ ๋ฉ๋๋ค.
๋ํ ์ฑ ์์๋ ์ธ๊ฐ์ด๋ผ๋ ์์๋ฅผ ๊ณ ๋ คํด์ผ ํ๋ค๊ณ ํ๋๋ฐ ์ฌ๋์ด ํ๋ ๋ง์ฐ์ค ํด๋ฆญ์ฒ๋ผ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๋ ฅ์ด ์ผ์ด๋๋ ๋ง์ ์ํฉ๋ค์์ I/O ์๋์ ๋น๋๋ ๊ธฐ์ ์ ์ธ ์ธก๋ฉด์๋ง ์์กดํ์ง ์์ผ๋ฉฐ ๋์คํฌ๋ ๋คํธ์ํฌ๋ณด๋ค ๋๋ฆด ์ ์๋ค๊ณ ํฉ๋๋ค.
- Node.js์ I/O
Node.js์ I/O๋ ํ์ผ ์์คํ , ๋คํธ์ํฌ, ๋ฐ์ดํฐ๋ฒ ์ด์ค, API ์์ฒญ ๋ฑ๊ณผ์ ์ํธ์์ฉ์ ์๋ฏธํฉ๋๋ค
์ด ๋์๋ค์ ๋์คํฌ, ๋คํธ์ํฌ๋ฑ์ ์ ๊ทผํด์ผ ํ๋ฏ๋ก CPU, RAM์ ๋นํด ์ ๊ทผํ๋๋ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฝ๋๋ค.
๋ธ๋กํน I/O
์ ํต์ ์ธ ๋ธ๋กํน I/O ํ๋ก๊ทธ๋๋ฐ์์๋ I/O๋ฅผ ์์ฒญํ๋ ํจ์์ ํธ์ถ์ ์์ ์ด ์๋ฃ๋ ๋๊น์ง ์ค๋ ๋์ ์คํ์ ์ฐจ๋จํฉ๋๋ค. ์ฐจ๋จ ์๊ฐ์ ์ ์ค๋ช ํ ๊ฒ์ฒ๋ผ ๋์คํฌ ์ ๊ทผ, ๋คํธ์ํฌ ์ ๊ทผ ๋ฑ์ I/O ์์ ์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํ๋ฏ๋ก ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๊ณ , ์ฌ์ฉ์ ์ก์ ์ ์ํด ๋ฐ์ดํฐ๊ฐ ์์ฑ๋๋ ๊ฒฝ์ฐ ๋ช ๋ถ๊น์ง ์์๋๊ธฐ๋ ํฉ๋๋ค. ๋ธ๋กํน I/O๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํ๋ ์น ์๋ฒ๊ฐ ๊ฐ์ ์ค๋ ๋ ๋ด์์ ์ฌ๋ฌ ์ฐ๊ฒฐ์ ์ฒ๋ฆฌํ์ง ๋ชปํ๋ ๊ฒ์ ๋น์ฐํ ์ผ์ด๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ ํต์ ์ธ ์ ๊ทผ ๋ฐฉ๋ฒ์ ๊ฐ๊ฐ์ ๋์ ์ฐ๊ฒฐ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด์ ๊ฐ๋ณ์ ์ค๋ ๋ ๋๋ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.

์ ์ด๋ฏธ์ง์์ ์ฃผ์ ๊น๊ฒ ๋ณผ ๊ฒ์ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ธฐ ์ํด ๊ฐ ์ค๋ ๋๊ฐ ์ ํด ์๊ฐ์ ๊ฐ๋ ๋ถ๋ถ์ ๋๋ค.
I/O์ ์์ ๊ฒฐ๊ณผ๋ฅผ ์ํด์ ์ค๋ ๋๊ฐ ๊ฝค ๋ง์ด ๋ธ๋กํน๋๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์ค๋ ๋๋ ์ปค๋ฅ์ ์ฒ๋ฆฌ๋ฅผ ์ํด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋ชจํ๊ณ ์ปจํ ์คํธ ์ ํ์ ์ ๋ฐํ์ฌ ๋๋ถ๋ถ์ ์๊ฐ ๋์ ์ฌ์ฉํ์ง ์์ ์ฅ์๊ฐ ์คํ ์ค๋ ๋๋ฅผ ๊ฐ์ง๊ฒ ๋จ์ผ๋ก์จ ๋ฉ๋ชจ๋ฆฌ์ CPU ์ฌ์ดํด์ ๋ญ๋นํ๊ฒ ๋ฉ๋๋ค.
๋ ผ ๋ธ๋กํน I/O
๋๋ถ๋ถ์ ์ต์ ์ด์์ฒด์ ๋ ๋ฆฌ์์ค์ ์ ๊ทผํ๊ธฐ ์ํด ๋ธ๋กํน I/O ์ธ์๋ ๋ ผ ๋ธ๋กํน I/O๋ผ๊ณ ๋ถ๋ฆฌ๋ ๋ค๋ฅธ ๋ฉ์ปค๋์ฆ์ ์ง์ํฉ๋๋ค. ์ด ์ด์ ๋ชจ๋์์๋ ๋ฐ์ดํฐ๊ฐ ์ฝํ์ง๊ฑฐ๋ ์ฐ์ฌ์ง๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ํญ์ ์ฆ์ ๋ฐํ๋ฉ๋๋ค. ์ด๋ฌํ ์ข ๋ฅ์ ๋ ผ ๋ธ๋กํน I/O๋ฅผ ๋ค๋ฃจ๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํจํด์ ์ค์ ๋ฐ์ดํฐ๊ฐ ๋ฐํ๋ ๋๊น์ง ๋ฃจํ ๋ด์์ ๋ฆฌ์์ค๋ฅผ ์ ๊ทน์ ์ผ๋ก ํด๋ง(poll)ํ๋ ๊ฒ์ด๋ผ๊ณ ํ๋๋ฐ์ ์ด๊ฒ์ ๋ฐ์ ๋๊ธฐ(busy-waiting)์ด๋ผ๊ณ ํฉ๋๋ค.
์ฑ ์ ์์ ์ฝ๋๊ฐ ๋์ค๋๋ฐ ์ด ์ฝ๋๋ฅผ ๋ณด์๋ฉด ๋ฐ์ ๋๊ธฐ๊ฐ ์ด๋ค ๋ป์ธ์ง ์ดํดํ์ค ์ ์์๊ฒ๋๋ค.
resources = [socketA, socketB, fileA]
while (!resources.isEmpty()) {
for (resource of resources) {
// ์ฝ๊ธฐ๋ฅผ ์๋
data = resource.read()
if (data === NO_DATA_AVAILABLE) {
// ์ด ์๊ฐ์๋ ์ฝ์ ๋ฐ์ดํฐ๊ฐ ์์
continue
}
if (data === RESOURCE_CLOSED) {
// ๋ฆฌ์์ค๊ฐ ๋ซํ๊ณ ๋ฆฌ์คํธ์์ ์ญ์
resources.remove(i)
} else {
// ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ณ ์ฒ๋ฆฌ
consumeData(data)
}
}
}
์ฝ๋๋ฅผ ๋ณด์๋ฉด while์ ์กฐ๊ฑด์ผ๋ก resources๊ฐ ๋น์ด ์์ง ์์๋๊น์ง for ๋ฃจํ๋ฅผ ๊ณ์ ๋๋ฉด์ ๋ฆฌ์์ค๋ฅผ ํด๋งํ๊ณ ์๋๊ฑธ ํ์ธํ ์ ์์ต๋๋ค.
๋ณด๋ค์ํผ ๊ฐ๋จํ ๊ธฐ๋ฒ์ผ๋ก ์๋ก ๋ค๋ฅธ ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ์ค๋ ๋ ๋ด์์ ์ฒ๋ฆฌํ ์ ์์ง๋ง ์ฌ์ ํ ํจ์จ์ ์ด์ง ์์ต๋๋ค. ์ ์์ ์์ ๋ฃจํ๋ ์ฌ์ฉํ ์ ์๋ ๋ฆฌ์์ค๋ฅผ ๋ฐ๋ณตํ๋ ๋ฐ์ ์์คํ CPU๋ฅผ ์ฌ์ฉํ๊ณ , ํด๋ง ์๊ณ ๋ฆฌ์ฆ์ ์์ฒญ๋ ์๊ฐ์ ๋ญ๋น๋ฅผ ์ด๋ํฉ๋๋ค.
์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์ฑ
๋ฐ์ ๋๊ธฐ(Busy-waiting)๋ ๋ ผ ๋ธ๋กํน ๋ฆฌ์์ค ์ฒ๋ฆฌ๋ฅผ ์ํ ์ด์์ ์ธ ๊ธฐ๋ฒ์ด ์๋๋๋ค. ๋คํํ๋, ๋๋ถ๋ถ์ ์ด์์ฒด์ ๋ ๋ ผ ๋ธ๋กํน ๋ฆฌ์์ค๋ฅผ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ธฐ๋ณธ์ ์ธ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
์ด ๋ฉ์ปค๋์ฆ์ ์ด ๋ฉ์ปค๋์ฆ์ ๋๊ธฐ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์(Synchronous Event Demultiplexer) ๋๋ ์ด๋ฒคํธ ํต์ง ์ธํฐํ์ด์ค(Event Notification Interface) ๋ผ๊ณ ํฉ๋๋ค.
์ฑ ์์๋ ์ค๋ช ํ์ง๋ง ์ด ์ฉ์ด๊ฐ ์ต์ํ์ง ์์ต๋๋ค. ๋ฉํฐ ํ๋ ์ฑ๊ณผ ๋๋ฉํฐํ๋ ์ฑ์ด ๋ญ์ง ์ฐพ์๋ดค์ต๋๋ค.
์ ๊ฐ ์ ๋ชฉ์ ๋งํฌํ ์ํค์ ์ฑ ์์ ๋ฉํฐ ํ๋ ์ฑ์ ํต์ ๋ถ์ผ, ์ ๊ธฐํต์ ๋ถ์ผ, ๋คํธ์ํฌ๋ฑ ์ฌ๋ฌ๋ถ์ผ์์ ์ฌ์ฉ๋๋ ๊ฐ๋ ์ด๋ผ๊ณ ํฉ๋๋ค.
์์ฝํด๋ณด์๋ฉด ํ๋์ ์์์ ์ฌ๋ฌ ๊ฐ์ ์์ ์ด๋ ๋ฐ์ดํฐ์ ๋์์ ์ฌ์ฉํ๋๋ก ํ๋ ๊ธฐ์ ์ ๋๋ค. ์ฝ๊ฒ ๋งํด, ์ฌ๋ฌ ๊ฐ์ ์ฑ๋์ ํ๋์ ์ฑ๋๋ก ํฉ์ณ์ ์ฌ์ฉํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๋๋ฉํฐ ํ๋ ์ฑ์ ๋ฉํฐ ํ๋ ์ฑ์ ๋ฐ๋ ๊ฐ๋ ์ด๊ฒ ์ฃ ? ์๋์ ๊ตฌ์ฑ ์์๋ก ๋ค์ ๋ถํ ๋๋ ์์ ์ ๋๋ค.
๋ค์ ๋์์์ ๋๊ธฐ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์๋ฅผ ์ฑ ์์๋ ์๋์ ๊ฐ์ด ์ค๋ช ํ๋ฉฐ ์์ ์ฝ๋๋ฅผ ๋ณด์ฌ์ค๋๋ค.
๋๊ธฐ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์๋ ์ฌ๋ฌ ๋ฆฌ์์ค๋ฅผ ๊ด์ฐฐํ๊ณ ์ด ๋ฆฌ์์ค๋ค ์ค์ ์ฝ๊ธฐ ๋๋ ์ฐ๊ธฐ ์ฐ๊ฐ์ ์คํ์ด ์๋ฃ๋์์๋ ์๋ก์ด ์ด๋ฒคํธ๋ฅผ ๋ฐํํฉ๋๋ค. ์ฌ๊ธฐ์ ์ฐพ์ ์ ์๋ ์ด์ ์ ๋๊ธฐ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์๊ฐ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์๋ก์ด ์ด๋ฒคํธ๊ฐ ์์ ๋๊น์ง ๋ธ๋กํน๋๋ค๋ ๊ฒ์ ๋๋ค.
while (events = demultiplexer.watch(watchedList)) { // 2
// ์ด๋ฒคํธ ๋ฃจํ
for (event of events) { // 3
// ๋ธ๋กํนํ์ง ์์ผ๋ฉฐ ํญ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํ
data = event.resource.read()
if (data === RESOURCE_CLOSED) {
// ๋ฆฌ์์ค๊ฐ ๋ซํ๊ณ ๊ด์ฐฐ๋๋ ๋ฆฌ์คํธ์์ ์ญ์
demultiplexer.unwatch(event.resource)
} else {
// ์ค์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ผ๋ฉด ์ฒ๋ฆฌ
consumeData(data)
}
}
}
์๊น ์ฝ๋์ ๋ค๋ฅธ์ ์ด ๋ณด์ด์๋์? while์ ์กฐ๊ฑด์ด ๋ฐ๋๊ณ , ์ฝ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃจํ๋ฅผ ๋๋ฉฐ(continue๋ฅผ ์ฌ์ฉํ๋ฉฐ) ๊ณ์ํด์ ์ฒดํฌํ์ง ์์ต๋๋ค.
์ฑ ์์ ์ด ์ฝ๋์ ๋ํ ์ค๋ช ์ ํฉ๋๋ค.
๊ฐ ๋ฆฌ์์ค๊ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ(List)์ ์ถ๊ฐ๋ฉ๋๋ค. ๊ฐ ๋ฆฌ์์ค๋ฅผ ํน์ ์ฐ์ฐ๊ณผ ์ฐ๊ฒฐํฉ๋๋ค.
๋๋ฉํฐํ๋ ์๊ฐ ๊ด์ฐฐ๋ ๋ฆฌ์์ค ๊ทธ๋ฃน๊ณผ ํจ๊ป ์ค์ ๋ฉ๋๋ค. demultiplexer.watch()๋ ๋๊ธฐ์์ผ๋ก ๊ด์ฐฐ๋๋ ๋ฆฌ์์ค๋ค ์ค์์ ์ฝ์ ์ค๋น๊ฐ ๋ ๋ฆฌ์์ค๊ฐ ์์ ๋๊น์ง ๋ธ๋กํน๋ฉ๋๋ค. ์ค๋น๋ ๋ฆฌ์์ค๊ฐ ์๊ธฐ๋ฉด, ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์๋ ์ฒ๋ฆฌ๋ฅผ ์ํ ์๋ก์ด ์ด๋ฒคํธ ์ธํธ๋ฅผ ๋ฐํํฉ๋๋ค.
์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์์์ ๋ฐํ๋ ๊ฐ ์ด๋ฒคํธ๊ฐ ์ฒ๋ฆฌ๋ฉ๋๋ค. ์ด ์์ ์์ ๊ฐ ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ฆฌ์์ค๋ ์ฝ์ ์ค๋น ๋ฐ ์ฐจ๋จ๋์ง ์๋ ๊ฒ์ด ๋ณด์ฅ๋ฉ๋๋ค. ๋ชจ๋ ์ด๋ฒคํธ๊ฐ ์ฒ๋ฆฌ๋๊ณ ๋๋ฉด, ์ด ํ๋ฆ์ ๋ค์ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์๊ฐ ์ฒ๋ฆฌ ๊ฐ๋ฅํ ์ด๋ฒคํธ๋ฅผ ๋ฐํํ๊ธฐ ์ ๊น์ง ๋ธ๋กํน๋ฉ๋๋ค. ์ด๋ฅผ ์ด๋ฒคํธ ๋ฃจํ(event loop)๋ผ๊ณ ํฉ๋๋ค.
์ฌ๊ธฐ์ ํฅ๋ฏธ๋ก์ด ์ ์ ์ฐ๋ฆฌ๊ฐ ์ด ํจํด์ ์ด์ฉํ๋ฉด ๋ฐ์ ๋๊ธฐ(Busy-waiting) ๊ธฐ์ ์ ์ด์ฉํ์ง ์๊ณ ๋ ์ฌ๋ฌ I/O ์์ ์ ๋จ์ผ ์ค๋ ๋ ๋ด์์ ๋ค๋ฃฐ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ก์จ ์ฐ๋ฆฌ๊ฐ ๋๋ฉํฐํ๋ ์ฑ์ ๋ํด ๋ ผํ๋ ์ด์ ๊ฐ ๋ช ํํด์ก์ต๋๋ค.
์๋ ๊ทธ๋ฆผ์์ ๋ณด์ฌ์ฃผ๋ฏ์ด ์ค์ง ํ๋์ ์ค๋ ๋๋ง์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋์์ ๋ค์ค I/O ์ฌ์ฉ ์์ ์ ๋์ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.

๊ทธ๋ฆฌ๊ณ ์ฑ ์์๋ ํ๋์ ์ค๋ ๋๋ฅผ ๊ฐ์ง I/O ๋ชจ๋ธ์ด ๊ฐ์ง๋ ์ฅ์ ์ผ๋ก ๋์์ฑ์ ์ ๊ทผํ๋ ๋ฐฉ์์ ์ด๋ก์ด ์ํฅ์ ๋ฏธ์น ์ ์๋ค๊ณ ํ๋ฉฐ ์ฑ ํ๋ฐ๋ถ์ ์ค๋ช ํ๋ค๊ณ ํฉ๋๋ค.(์ถํ ํฌ์คํ ์ ํด๋ณด๊ฒ ์ต๋๋ค.)
Reactor ํจํด
์ด์ ๋๋์ด Reactor ํจํด์ ๋๋ค. ์ฑ ๋ด์ฉ์ ๋ณผ๊น์?
๋ฆฌ์กํฐ ํจํด์ ์ด๋ฉด์ ์๋ ์ฃผ๋ ์์ด๋์ด๋ ๊ฐ I/O ์์ ์ ์ฐ๊ด๋ ํธ๋ค๋ฌ๋ฅผ ๊ฐ๋๋ค๋ ๊ฒ์ ๋๋ค. Node.js์์์ ํธ๋ค๋ฌ๋ ์ฝ๋ฐฑ ํจ์์ ํด๋นํฉ๋๋ค. ์ด ํธ๋ค๋ฌ๋ ์ด๋ฒคํธ๊ฐ ์์ฑ๋๊ณ ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ์ฒ๋ฆฌ๋๋ ์ฆ์ ํธ์ถ๋๊ฒ ๋ฉ๋๋ค. ๋ฆฌ์กํฐ ํจํด์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.

์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์์ ์์ฒญ์ ์ ๋ฌํจ์ผ๋ก์จ ์๋ก์ด I/O ์์ ์ ์์ฑํฉ๋๋ค. ๋ํ, ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ์ด ์๋ฃ๋์์ ๋ ํธ์ถ๋ ํธ๋ค๋ฌ๋ฅผ ๋ช ์ํฉ๋๋ค. ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์์ ์ ์์ฒญ์ ์ ๋ฌํ๋ ๊ฒ์ ๋ ผ ๋ธ๋กํน ํธ์ถ์ด๋ฉฐ, ์ ์ด๊ถ์ ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ์ฆ์ ๋ฐํ๋ฉ๋๋ค.
์ผ๋ จ์ I/O ์์ ๋ค์ด ์๋ฃ๋๋ฉด ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์๋ ๋์ํ๋ ์ด๋ฒคํธ ์์ ๋ค์ ์ด๋ฒคํธ ํ์ ์ง์ด ๋ฃ์ต๋๋ค.
์ด ์์ ์์ ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์ด๋ฒคํธ ํ์ ํญ๋ชฉ๋ค์ ์ํํฉ๋๋ค.
๊ฐ ์ด๋ฒคํธ์ ๊ด๋ จ๋ ํธ๋ค๋ฌ๊ฐ ํธ์ถ๋ฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์ ์ผ๋ถ์ธ ํธ๋ค๋ฌ์ ์คํ์ด ์๋ฃ๋๋ฉด ์ ์ด๊ถ์ ์ด๋ฒคํธ ๋ฃจํ์ ๋๋๋ ค์ค๋๋ค(5a). ํธ๋ค๋ฌ ์คํ ์ค์ ๋ค๋ฅธ ๋น๋๊ธฐ ์์ ์ ์์ฒญํ ์ ์์ผ๋ฉฐ(5b), ์ด๋ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์์ ์๋ก์ด ํญ๋ชฉ์ ์ถ๊ฐํ๋ ๊ฒ์ ๋๋ค.(1)
์์ ๋ธ๋กํน I/O, ๋ ผ ๋ธ๋กํน I/O, ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์์ ๋ํ ๋ด์ฉ์ ์ ๋ถ ์ดํดํ์ จ๊ณ ๊ทธ๋ฆผ์ ๋ณด์ ๋ค๋ฉด Reactor ํจํด์ ์ ์ดํดํ์ค ์ ์์๊ฒ๋๋ค.
Reactor ํจํด์ ์ดํดํ ๋ ์ ์ํ ์
์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ฐฉ์(์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์)์ด ๋๊ธฐ๋ ๋น๋๊ธฐ๋์ ์ฐจ์ด๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์
์ฑ ์์ ์ค๋ช ํ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์ฑ๊ณผ ์ฐ๊ฒฐ์ง์ด Reactorํจํด์ ์ดํดํ ๋ ์ ์ํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
๊ตฌ๋ถ | ๋๊ธฐ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์ฑ | ๋ฆฌ์กํฐ ํจํด |
---|---|---|
์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ฐฉ์ | ์์ฐจ์ ์ฒ๋ฆฌ | ๋น๋๊ธฐ ์ฒ๋ฆฌ |
์ฝ๋ฐฑ ํจ์ ์คํ ๋ฐฉ์ | ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ์์๋๋ก ์คํ | ์ด๋ฒคํธ ๋ฐ์ ์ ๋ฑ๋ก๋ ํธ๋ค๋ฌ ์คํ |
์ฅ์ | ๊ตฌํ์ด ๋น๊ต์ ๊ฐ๋จ | ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ก ์ธํ ๋์ ์ฑ๋ฅ |
๋จ์ | ์ด๋ฒคํธ ์ฒ๋ฆฌ ์์ ๋ณ๊ฒฝ ์ด๋ ค์ | ํธ๋ค๋ฌ ๊ด๋ฆฌ ๋ณต์ก์ฑ ์ฆ๊ฐ |
Libuv, Node.js์ I/O ์์ง
๋ง์ง๋ง์ผ๋ก ์ด๋ฐ I/O ์์ง์ ๋ํ ๊ฐ OS์ ์ฐจ์ด๋ฅผ ๊ทน๋ณตํ๊ธฐ ์ํด Node.js๋ Libuv๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํฉ๋๋ค.
๊ฐ ์ด์์ฒด์ ๋ Linux์ epoll, macOs์ kqueue, Window์ IOCP(I/O completion port) API์ ๊ฐ์ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์๋ฅผ ์ํ ์์ฒด ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๊ฒ๋ค๊ฐ ๊ฐ I/O ์์ ์ ๋์ผํ OS ๋ด์์๋ ๋ฆฌ์์ค ์ ํ์ ๋ฐ๋ผ ๋งค์ฐ ๋ค๋ฅด๊ฒ ๋์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด Unix์์ ์ผ๋ฐ ํ์ผ ์์คํ ์ ๋ ผ ๋ธ๋กํน ์์ ์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ ผ ๋ธ๋กํน ๋์์ ์ํด์๋ ์ด๋ฒคํธ ๋ฃจํ ์ธ๋ถ์ ๋ณ๋์ ์ค๋ ๋๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์๋ก ๋ค๋ฅธ ์ด์์ฒด์ ๊ฐ์ ๋ถ์ผ์น์ฑ์ ์ด๋ฒคํธ ๋๋ฉํฐํ๋ ์๋ฅผ ์ํด ๋ณด๋ค ๋์ ๋ ๋ฒจ์ ์ถ์ํ๋ฅผ ํ์๋ก ํ๊ฒ ๋์์ต๋๋ค.
์ด๋ฌํ ์ด์ ๋ก Node.js ์ฝ์ดํ์ด Node.js๋ฅผ ์ฃผ์ ์ด์์ฒด์ ์์ ํธํ๋๊ฒ ํด์ฃผ๋ฉฐ ์๋ก ๋ค๋ฅธ ๋ฆฌ์์ค ์ ํ์ ๋ ผ ๋ธ๋กํน ๋์์ ํ์คํํ๊ธฐ ์ํด libuv๋ผ๊ณ ๋ถ๋ฆฌ๋ C ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค์์ต๋๋ค. Libuv๋ Node.js์ ํ์ ์์ค์ I/O ์์ง์ ๋ํํ๋ฉฐ ์๋ง๋ Node.js์ ๊ตฌ์ฑ์์ ์ค์์ ๊ฐ์ฅ ์ค์ํ๋ค๊ณ ๋งํ ์ ์์ต๋๋ค.
Libuv๋ ๊ธฐ๋ณธ ์์คํ ํธ์ถ์ ์ถ์ํํ๋ ๊ฒ ์ธ์๋ ๋ฆฌ์กํฐ ํจํด์ ๊ตฌํํ๊ณ ์์ผ๋ฏ๋ก ์ด๋ฒคํธ ๋ฃจํ์ ์์ฑ, ์ด๋ฒคํธ ํ์ ๊ด๋ฆฌ, ๋น๋๊ธฐ I/O ์์ ์ ์คํ ๋ฐ ๋ค๋ฅธ ์ ํ์ ์์ ์ ํ์ ๋ด๊ธฐ ์ํ API๋ค์ ์ ๊ณตํฉ๋๋ค.
๋ง์น๋ฉฐ
์ฌ์ค ์ ๋ ์ด ์ฑ ์ ์ดํ์ 2020๋ ์ ๊ตฌ์ ํด์ Reactor ํจํด์ ๋ํด ์ฝ์์ง๋ง ์ดํด๊ฐ ์๋์ง ์์์ต๋๋ค.
4๋ ์ด๋ ์๊ฐ์ด ํ๋ฌ ๋ค์ ๋ณด๋ ์ฌ๋ญ, ๊ทธ๋์๋ ๋ค๋ฅธ ๋๋์ผ๋ก ๋ค๊ฐ์ค๋ค์.
์ ์ ๊ฐ์ ๊ฒฝํ์ ํ์๋ ๋ถ๋ค์ด ๋ง์ผ์ค ๊ฑฐ๋ผ ์๊ฐํฉ๋๋ค.
์ถ์ฒ์ ๋ฐ์์ ์๊ฑฐ๋ ์ ๋ฌผ ๋ฐ์ ์ฑ ์ ์ฝ๋ค๊ฐ โ์ ! ๋๋์ฒด ๋ฌด์จ ๋ง์ธ์ง ํ๋๋ ๋ชจ๋ฅด๊ฒ ์ด!โ ํ๊ณ ๋ฎ์ด๋๋๋ฐ, ์๊ฐ์ด ์ง๋ ๋ค์ ์ฝ์ด๋ณด๋ฉด ์ดํด๊ฐ ๋๋ ๊ฒฝ์ฐ ๋ง์ด์ฃ .
์ด๋ฐ ๊ฒฝํ์ด ๋ด๊ฐ ์ฑ์ฅํ๊ณ ๋ฐ์ ํ๋ค๋ ๊ฒ์ ํ์ธํด ๋ณผ ์ ์๋ ๊ธฐํ๊ฐ ์๋๊น ํฉ๋๋ค.
์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.