๐ฑ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ด๋ป๊ฒ ๋์์ฑ์ ์ง์ํ ๊น?
๋ค๋ค ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ฑ๊ธ ์ค๋ ๋ ๊ธฐ๋ฐ ์ธ์ด๋ผ๊ณ ํ๋ค. ํ์ง๋ง ์ค์ ๋ก ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ์ฌ์ฉ๋๋ ๊ณณ๋ค์ ๋ณด๋ฉด, ๋ธ๋ผ์ฐ์ ์์ ์น ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด๊ณ ๋ฐ๋ ๋์ค์๋ ํ์ด์ง์ ๋๋๋ง ๋์์ ๋ฉ์ถ์ง ์๊ณ , node.js ์๋ฒ์์ ์ฌ๋ฌ ๊ฐ์ HTTP ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ๋ ํ๋ค.
์ฑ๊ธ ์ค๋ ๋ ๊ธฐ๋ฐ์์ ์ด๋ฌํ ์์
๋ค์ด ์ด๋ป๊ฒ ๊ฐ๋ฅํ์ง ์์๋ณด์.
์๋ฐ์คํฌ๋ฆฝํธ๋ ์ฑ๊ธ์ค๋ ๋ ์ธ์ด
javascript๋ย ์ฑ๊ธ์ค๋ ๋๋ก ๋์ํ๋ ์ธ์ด์ด๋ค. ์ฆ ํ๋์ ๋จ์ผ ๋ฉ์ธ ์ค๋ ๋๋ก ๊ตฌ์ฑ๋์ด ์๋ค.
์ฑ๊ธ์ค๋ ๋๋ ๋ง ๊ทธ๋๋กย ํ๋ฒ์ ํ๋์ ์์
๋ง ์ํํ ์ ์์์ ์๋ฏธํ๋ค. ๋ค๋ฅธ ์์
์ด ์ค๊ฐ์ ๋ผ์ด๋ค ์๋ ์๊ณ , ๊ธฐ์กด์ ์ํํ๋ ์์
์ด ๋๋์ผ๋ง ๊ทธ ๋ค์ ์์
์ ์ํํ ์ ์๋ค.
javascript๋ฅผ ์คํํ๋ ์์ง์ ํ๋์ Memory Heap๊ณผ Call Stack์ ๊ฐ๋๋ค.
- Memory Heap : ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ๋ด๋นํ๋ ๊ณณ.
- Call Stack : ์ฝ๋๊ฐ ํธ์ถ๋๋ฉด์, ์คํ์ผ๋ก ์์ด๋ ๊ณณ.
ํ๋์ ๋ฉ์ธ์ค๋ ๋์์ ํธ์ถ๋๋ ํจ์๋ค์ด ์ฝ์คํ์ ์์ผ๊ฒ์ด๊ณ , ์ด ํจ์๋ค์ย LIFO(Last In First Out)๋ฐฉ์์ผ๋ก ์คํ๋๋ค.
์ฝ์คํ๊ณผ ์ฑ๊ธ์ค๋ ๋๋ฅผ ์ฐ๊ด์ง์ด ์๊ฐํด๋ณด๋ฉด, javascript๊ฐ ํ๋์ ๋ฉ์ธ์ค๋ ๋์ ํ๋์ ์ฝ์คํ์ ๊ฐ๋๋ค๋ ๋ง์ด๋ค.
ํ์ง๋ง javascript์ ํน์ง๋ค์ ์์๋ณด๋ฉด ๋น๋๊ธฐ
, ๋์์ฑ
, ๋
ผ๋ธ๋กํน(Non Blocking) I/O
๋ฑ์ ์๋ฐ๋๋ ๊ฐ๋
๋ค์ด ๋ฑ์ฅํ๋ค.
์ฑ๊ธ์ค๋ ๋๋ผ๋ฉฐ? ์ด๋ป๊ฒ ๋์์ฑ์ ๊ฐ์ง ์ ์๋๊ฑฐ์ง?
๋์์ฑ์ ๋ณด์ฅํ๋ ๋น๋๊ธฐ, ๋ ผ๋ธ๋กํน ์์ ๋ค์ javascript ์์ง์ ๊ตฌ๋ํ๋ ๋ฐํ์(Runtime) ํ๊ฒฝ์์ ๋ด๋นํ๋ค. ์ฌ๊ธฐ์์ ๋ฐํ์ ํ๊ฒฝ์ด๋, ๋ธ๋ผ์ฐ์ ํน์ Node.js๋ฅผ ์๋งํ๋ค.
Node.js ๊ณต์์ฌ์ดํธ์์๋ Node.js๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์๊ฐํ๋ค.
Node.js๋ ๋น๋๊ธฐ ์ด๋ฒคํธ ์ฃผ๋ javaScript ๋ฐํ์์ผ๋ก์จ Node.js ๋ ํ์ฅ์ฑ ์๋ ๋คํธ์ํฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์๋๋ก ์ค๊ณ๋์์ต๋๋ค.
node.js ๊ตฌ์กฐ
Node.js๋ฅผ ํฌ๊ฒ ๋๋ ๋ดค์ ๋, ๋ด์ฅ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ v8์์ง ๊ทธ๋ฆฌ๊ณ ย libuv
๋ก ๊ตฌ์ฑ๋์ด ์๋ค. Node.js์ ํน์ฑ์ธ ์ด๋ฒคํธ ๊ธฐ๋ฐ, ๋
ผ๋ธ๋กํน I/O ๋ชจ๋ธ
๋ค์ ๋ชจ๋ย libuv ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๊ตฌํ๋๋ค.
libuv์ ๊ณต์ ํํ์ด์ง ์๊ฐ๋ ์๋์ ๊ฐ๋ค.
libuv is a multi-platform support library with a focus on asynchronous I/O. It was primarily developed for use by Node.js, but itโs also used by Luvit, Julia, uvloop, and others.
- Node.js๋ Javascript์ C++์ธ์ด๋ก ๊ตฌ์ฑ๋์ด ์๋ค.
V8์์ง๋ 70% ์ด์์ C++๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ, libuv๋ 100%์ C++์ธ์ด๋ก ๊ตฌ์ฑ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
-
Node.js์ ์ฝ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋
binding API
์ ํตํด javascript ํ๊ฒฝ์์ ์ฌ์ฉ๋ ์ ์๋ค. (์๋ฅผ ๋ค๋ฉด Node.js์ ๋ด์ฅ ๋ชจ๋์ธ crypto๋ ์๋ C++ ์ธ์ด๋ก ์์ฑ๋์ด ์๋ค๊ณ ํ๋ค) -
Node.js์ ๋์ํ๋ ์ด๋ฒคํธ ๋ฃจํ๋ libuv ๋ด์์ ๊ตฌํ๋๋ค. ์ด๋ฒคํธ ๋ฃจํ๊ฐ libuv ๋ด์์ ์คํ๋๋ค๊ณ ํด์, Javascript์ ์ค๋ ๋์ ์ด๋ฒคํธ ๋ฃจํ์ ์ค๋ ๋๊ฐ ๋ณ๋๋ก ์กด์ฌํ๋ค๊ณ ์๊ฐํ ์๋ ์์ง๋ง, Node.js๋ ์ฑ๊ธ์ค๋ ๋์ด๊ธฐ ๋๋ฌธ์ ํ๋์ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ๊ฐ์ง๋ฉฐ, ํ๋์ ์ค๋ ๋๊ฐ ๋ชจ๋ ๊ฒ์ ์ฒ๋ฆฌํ๋ค.
์ด๋ฒคํธ ๋ฃจํ
์ด๋ฒคํธ์ ๋ฐ๋ผ ํธ์ถ๋๋ ์ฝ๋ฐฑํจ์๋ฅผ ๊ด๋ฆฌํ๋ ์ญํ ์ ๋ด๋นํ๋ค.
-
์ด๋ฒคํธ ๋ฃจํ๊ฐ ํ์คํฌ ํ์์ ์ฝ์คํ์ผ๋ก ์ฝ๋ฐฑ ํจ์๋ฅผ ๋๊ฒจ์ฃผ๋ ์์ ์ ์ฝ์คํ์ ์์ฌ์๋ ํจ์๊ฐ ์์๋๋ง ์ํ๋๋ค.
-
๋ฐ๋ผ์ ์ฝ์คํ์ ๋ง์ ํจ์๋ค์ ์์ ๋๋ ๊ฒ๋ค์ ๋ค๋ฅธ ํ์คํฌ๋ค์ ๋ธ๋กํนํ ์ฌ์ง๋ฅผ ๋์ด๊ฒ ๋๋ค.
๋ฐ๋ผ์
์คํ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์ฝ๋๋ค์ ์ ์ ํ๊ฒ ํ์คํฌ๋ค์ ์ธ๋ถํํ์ฌ ๋น๋๊ธฐ ํธ์ถ
ํ์ฌ ์ฑ๋ฅ์ ๊ฐ์ ํ ์ ์๋ค. -
๋งค ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ฉฐ ์ํ๋๋ Event Loop๋ ์ฑ๊ธ ์ฐ๋ ๋์ด๋ฉฐ ํ ๋ฒ์ ํ๋์ ์ด๋ฒคํธ๋ง ์ฒ๋ฆฌํ ์ ์๋ค.
-
์ด๋ฒคํธ ๋ฃจํ๋ **์ฌ๋ฌ ๊ฐ์ ํ์ด์ฆ(Phase)**๋ค์ ๊ฐ๊ณ ์์ผ๋ฉฐ, ํด๋น ํ์ด์ฆ๋ค์ **๊ฐ์๋ง์ ํ(Queue)**๋ฅผ ๊ฐ๋๋ค.
-
์ด๋ฒคํธ ๋ฃจํ๋ ๋ผ์ด๋ ๋ก๋น(round-robin) ๋ฐฉ์์ผ๋ก ๋ ธ๋ ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ์ผ์ ๊ท์น์ ๋ฐ๋ผ ์ฌ๋ฌ ๊ฐ์ ํ์ด์ฆ๋ค์ ๊ณ์ ์ํํ๋ค.
setTimeout(() => {
console.log('timeout');
}, 0);
setImmediate(() => {
console.log('immediate');
});
์ ์ฝ๋์์ ์ด๋ ๊ฒ์ด ๋จผ์ ์ถ๋ ฅ์ด ๋ ๊น? ์ ๋ต์ ์ ์ ์๋ค
์ด๋ค.
-
setTimeout์ ์ด๋ฒคํธ ๋ฃจํ์ timer๋จ๊ณ์์ ์ฒ๋ฆฌ๋๊ณ , setImmediate๋ check๋จ๊ณ์์ ์ฒ๋ฆฌ๋๋ค.
-
์ด๋ฒคํธ ๋ฃจํ๋ ์ฑ๊ธ ์ค๋ ๋๋ก ๊ณ์ํด์ ํ์ด์ฆ๊ฐ ๋ณํํ๋ฏ๋ก, ํ์ฌ ์ด๋ ํ์ด์ฆ์ธ์ง์ ๋ฐ๋ผ ๋์ ์คํ ์์๋ ๋ฌ๋ผ์ง๊ฒ ๋๋ค.
๋ ผ๋ธ๋กํน (Non-Blocking)
- Node.js์์์ ๋ ผ๋ธ๋กํน ๋ชจ๋ธ์ Input๊ณผ Output์ด ๊ด๋ จ๋ ์์ (http, Database CRUD, third party api, filesystem), ์ค๋ซ๋์ CPU๋ฅผ ์ฌ์ฉํด์ผํ๋ ์์ ๋ฑ์ ๋ธ๋กํน ์์ ๋ค์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ํํ๊ณ , ์ด๋ฅผ ๋น๋๊ธฐ ์ฝ๋ฐฑํจ์๋ก ์ด๋ฒคํธ ๋ฃจํ์ ์ ๋ฌํ๋ ๊ฒ์ ๋งํ๋ค.
- ์ฌ๊ธฐ์ ๋ฐฑ๊ทธ๋ผ์ด๋๋ OS ์ปค๋ ํน์ libuv์ ์ค๋ ๋ ํ์ ์๋ฏธํ๋ค.
- libuv๋ OS ์ปค๋์์ ์ด๋ค ๋น๋๊ธฐ ์์ ๋ค์ ์ง์ํด์ฃผ๋์ง ์๊ณ ์๊ธฐ๋๋ฌธ์, ์์ ์ข ๋ฅ์ ๋ฐ๋ผ ์ปค๋ ํน์ ์ค๋ ๋ ํ๋ก ๋ถ๊ธฐํ๋ค.
- ์์ ์ด ์๋ฃ๋๋ฉด ์ด๋ฒคํธ๋ฃจํ์๊ฒ ์ด๋ฅผ ์๋ ค์ฃผ๊ณ , ์ด๋ฒคํธ ๋ฃจํ์ ์ฝ๋ฐฑํจ์๋ก ๋ฑ๋ก๋๋ค.
๋์์ฑ์ ์๋ฏธ
์ฌ์ค ๋์์ฑ์ ์๋ฏธ๊ฐ ์ ๋ง๋ก javascript ์ฝ๋๊ฐ ๋์์ ์คํ๋๋๊ฑธ ์๋ฏธํ๋ ๊ฑด ์๋๋ค.
์ด์ฐจํผ ๋น๋๊ธฐ ์์
์ ๋์ Event Loop๋ฅผ ํตํด ๊ฒฐ๊ตญ์ javascript ์์ง์ ๋จ์ผ Call Stack
์ผ๋ก ์ค๊ฒ ๋์ด์๋ค.
์์์ ๋งํ๋ฏ์ด javascript๋ ๊ฒฐ๊ตญ์ ์ฑ๊ธ ์ค๋ ๋ ์ธ์ด์ด๊ณ , ์ด ํต์ฌ์ ๋ณํ์ง ์๋๋ค.
(single thread โ single call stack โ single thing at a time)
์ฒ์๋ถํฐ ๋ฉํฐ์ค๋ ๋๋ฅผ ์ง์ํ๊ฒ ๋ง๋ค๋ฉด ๋์ง ์์์๊น?
์ฌ์ค ์ด๋ด๊ฑฐ๋ฉด ์ธ์ด ์ฐจ์์์ ๊ทธ๋ฅ ๋ฉํฐ ์ฐ๋ ๋๋ฅผ ์ง์ํ๋๊ฒ ๋ซ์ง ์์์๊น?
ํ๋ ์๊ฐ์ด ๋ ๋ค.
ํ์ง๋ง javascript๊ฐ ์ด๋ ๊ฒ ์ค๊ณ๋ ์ด์ ๋ ์ฑ๊ธ ์ฐ๋ ๋๊ฐ ์ ์ผ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ๊ฐํธํ ๋ฐฉ๋ฒ์ด๊ธฐ ๋๋ฌธ์ด์๋ ๊ฒ ๊ฐ๋ค.
์ฌ์ค javascript๊ฐ ๊ฐ๋ฐ๋๋ ์์ ์๋ ์ค๋ ๋ ์ฒ๋ผ ๋ณต์กํ ์์
์ ์๊ตฌํ์ง ์์์ ๊ฒ์ด๋ค.
๋ฌด์๋ณด๋ค๋ DOM์ ์กฐ์ํ ๋ ๋ฉํฐ์ค๋ ๋๋ผ๋ฉด ํ์ด๋ฐ์ด ์ด๊ธ๋๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ํ๋ค ๊ฑฐ๋ผ ์๊ฐ๋๋ค.
ios๋ android์์๋ UI์ ๋ํ ๋ณ๊ฒฝ์ UI thread(main thread)์์๋ง ๊ฐ๋ฅํ ๊ฒ์ผ๋ก ์๊ณ ์๋ค.
๋ํ ์ด๋ฏธ ์คํ์ ์ง์ฐํ๊ฑฐ๋ ๋ถ๊ธฐํ ์ ์๋ ์ด๋ฒคํธ ๊ฐ๋ ์ด ์๊ธฐ ๋๋ฌธ์ ๋ฉํฐ์ค๋ ๋๋ ๋ณต์ก์ฑ๋ง ๋๋ฆด ๋ฟ์ด๋ผ๊ณ ์๊ฐ๋๋ค.
๋ด๊ฐ ์ ์ฉํ๋ python(CPython ๊ธฐ์ค)๋ ๋ฉํฐ ์ฐ๋ ๋๋ก ์ฝ๋๋ฅผ ์ง๋, ์ค์์ python ์ธํฐํ๋ฆฌํฐ์ ํ๋์ ์ค๋ ๋์์๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ
GIL(Global Iterpreter Lock)
์ด๋ผ๋ ๊ฐ๋ ์ด ์๋ค.
์ด ์ญ์ python์์ thread-safe ๊ด๋ จํ ๋ฌธ์ ๋ค์ ๊ฐ์ฅ ๊ฐ๋จํ๊ฒ ํด๊ฒฐํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ด์์ ๊ฒ์ด๋ผ๋ ์๊ฐ์ด ๋ ๋ค.
์์ฆ์ ์คํ๋ง๋ ๊ธฐ์กด ์๋ธ๋ ๋ฐฉ์(1์์ฒญโ1์ค๋ ๋)์์, ์ด๋ฒคํธ ๋ฃจํ ๊ธฐ๋ฐ์ผ๋ก ๋๋์ ํด๋ผ์ด์ธํธ ์์ฒญ ์ฒ๋ฆฌ์ ๋ ์ ํฉํ WebFlux๋ ๋ง์ด ์ฌ์ฉํ๋ ์ถ์ธ์ธ ๊ฒ ๊ฐ๋ค.
๊ฐ ๊ตฌ์กฐ๋ง๋ค์ ์ฅ๋จ์ ์ด ํ์คํ ์กด์ฌํ๊ณ ๊ฒฐ๊ตญ์ ์ ํ์ ๋ฌธ์ ์ธ ๊ฒ ๊ฐ๋ค.
์ฐธ๊ณ
Welcome to the libuv documentation - libuv documentation
๋ธ๋กํน๊ณผ ๋ ผ๋ธ๋กํน ์ดํด๋ณด๊ธฐ | Node.js
The Node.js Event Loop, Timers, and process.nextTick
Javascript ๋์์๋ฆฌ (Single thread, Event loop, Asynchronous)