간단히 말하면 Node.js는 서버사이드에서 동작이 가능한 Javascript이지만 보통 서버사이드 자바스크립트라고 하면 생각할만한건 runat="server"같은 수준의 서버사이드 자바스크립트와는 차원자체가 다릅니다. 또한 Jaxer나 Narwhar같은 서버스크립트 자바스크립트 환경도 존재하지만 Node.js는 약간 다릅니다. 원래는 nettues+의 Learning Server-Side JavaScript with Node.js를 따라하면서 포스팅을 하려고 하였지만 Node.js를 만든 Ryan Dahl가 JSConf 2009에서 발표한 동영상을 보는 것이 훨씬 이해하기가 좋아서 Ryan Dahl의 발표영상을 링크합니다.
Ryan Dahl: Node.js
동영상에 나오는 발표자료는 글자가 잘 보이지 않아서 Scribd에 올라와 있는 발료자료입니다. (JSConf정도 행사에 node.js같은 프로젝트를 들고 나오는 사람이 헤져서 글자도 잘 보이지 않는 나이키티셔츠를 걸치고 나와서 한다는 것이 재밌기도 하네요.)
Node.js JSConf 2009
Node.js는 서버사이드 자바스크립트이며 Google의 자바스크립트 엔진인 V8이 빌트인되어 있습니다. Event 기반이며 non-blocking I/O를 지원합니다. 자바스크립트의 표준라이브러리 프로젝트인 CommonJS의모듈시스템을 지원합니다.
Apache같은 웹서버들은 모든 요청마다 시스템 쓰레드를 생성하는 쓰레드 기반이고 대부분의 경우에는 잘 동작하지만 Friendfeed나 Google Wave같은 리얼타임 애플리케이션처럼 많은 long-lived커넥션을 사용하는 애클리케이션에는 적합하지 않고 확장(scale)하기가 어렵습니다. 위 프리젠테이션에서 Apache와 NGINX를 비교한 그래프를 보면 쓰레드기반인 Apache는 요청이 늘어날수록 메모리가 증가하지만 NGINX는 직선을 유지하는 것을 볼 수가 있습니다. 이는 NGINX는 Event Loop를 사용하기 때문입니다.
이런 쓰레드기반의 문제를 Event Loop를 이용하면 해결할 수 있습니다.(여기서 Event Loop라는 것은 동작을 요청한뒤에 콜백을 지정하여 동작이 완료되면 콜백이 실행되는 방식을 발합니다.) 그럼 왜 모두가 Event Loop를 사용하지 않는가하는 의문이 생깁니다.
Ryan Dahl은 문화적인(Cultural) 이유와 구조적(infrastructural)인 이유 2가지가 있다고 생각하였습니다.
문화적인 이유는 우리가 프로그래밍을 배울때 인풋을 요청하면 요청한 인풋을 받을때까지 아무것도 하지 말라고 배웠기 때문입니다.
puts("Enter your name: ");
var name = gets();
puts("Name: " + name);
위 코드는 인풋을 받아서 출력하는 익숙한 코드입니다. 인풋이 들어올때까지 아무것도 행하지 않습니다.
puts("Enter your name: ");
gets(function(name) {
puts("Name: " + name);
});
이벤트 루프방식인 위와같은 코드는 복잡하다는 이유로 거부되어 왔습니다.
구조적인 이유는 싱글쓰레드이벤트 루프는 논블럭킹 I/O를 요구하지만 대부분의 라이브러리들은 그렇지 않았습니다. POSIX I/O나 DB라이브러리들은 비동기요청을 지원하지 않았습니다. 하지만 현재는 EventMachine, Twisted등 좋은 이벤트루프 플랫폼이 존재하고 있지만 사용자들은 어떻게 다른 라이브러리들과 이것들은 조합할수 있을지 혼란스러워 하고 있으며 서버사이드 개발자들은 이벤트 루프와 넌블락킹 I/O에 대한 지식이 필요합니다.
하지만 Javascript는 Event Loop를 사용하도록 디자인되어 비동기 펑션과 클로져를 지원하고 한번에 하나의 콜백만 실행하며 DOM 이벤트 콜백을 통한 I/O를 지원하고 있습니다. 더군다나 자바스크립트의 문화는 이미 이벤트기반의 프로그래밍에 익숙해져 있습니다.
Design Goal
- Function은 직접 플랫폼 I/O에 접속하지 않습니다.
- Disk, network, 프로세스를 통해 데이터를 받기 위해서는 반드시 콜백(callback)을 사용합니다. 콜백을 사용할 수도 있습니다. (함수명sync()라는 함수들이 제공되고 있다는 AJ님의 제보에 따라 수정하였습니다. 위 PT의 28페이지에 must be라는 표현으로 보아 보통의 경우 callback을 권장하는 것으로 추측(?)됩니다.)
- TCP, DNS, HTTP같은 프로토콜을 지원합니다.
- HTTP feature를 지원합니다.(Chunk된 requst/response, Keep-alive, Comet을 위한 리퀘스트 홀딩
- 클라이언트 사이드 자바스크립트 프로그래밍과 과거 학생때 배운 Unix 스타일에 친숙하게 디자인되었습니다.
Internal Design
- Google의 V8 사용
- Marc Lehmann이 만든 이벤트루프 라이브러리 libev 사용
- Marc Lehmann이 만든 쓰레드풀 라이브러리 libeio 사용
- Ryan Dahl이 만든 HTTP파서 http-parser 사용
- Ryan Dahl이 만든 libev에 기반한 스크림 소켓 라이브러리 evcom 사용
- Michael Tokarev가 만든 넌블럭킹 DNS resolver udns 사용
더 자세한 내용은 AJ님의 core perspective to node.js를 참고하시면 도움이 될 것입니다.
이 포스팅은 node.js는 무엇인가? #2 : Hello World 실행하기로 이어집니다.
안녕하세요. 저 오리궁뒤입니다.
정훈님의 node.js 자료 큰 도움이 되었습니다. 최근에 HTML5 관련해서 찾아보다가 여기까지 오게 되었네요. ^^
잘 지내시죠? 다음에 또 뵈어요~ ㅋ
앗.. 제 이름까지 기억하시고.. ㅎㅎ 잘 지내시죠? 미투데이에선 자주 보는데요 ㅎㅎㅎㅎㅎ node.js도 하시는건가요? ㅎㅎ 담에 또 뵈요 ㅎ
되새김질 할려고 글 또 읽다가
아래 AJ님의 링크가 바뀐것 같아서요.
core perspective to node.js http://ajaxian.kr/2010/05/15/core-perspective-to-nodejs/
아~ 그렇군요... ㅡㅡ;; (퍼머링크를 바꾸시다니.. ㅋ)
링크수정해놓겠습니다. 제보 감사합니다 ㅎㅎ
최근에 node.js에 대한 관심이 생겼는데 개념을 이해하는데 많은 도움이 됐습니다.
열심히 읽었다는 것을 증명(?) 하기 위해 오타 하나 제보합니다.
Apache같은 웹서버들은 (모등 -> 모든) 요청마다 시스템 쓰레드를 생성하는 쓰레드 기반
감사합니다.
오타제보 감사합니다. 수정하였습니다.
node.js에 관심있으시면 최근에 책도 나왔습니다. ㅎ
http://www.yuiblog.com/blog/2010/05/20/video-dahl/
요기 가면 Yahoo에서 엔지어를 대상으로 Ryan Dahl이 위 내용과 거의 같은 Slide ( 조금 고친것 같애요) 로 강의했는데 조금 더 정리된 모습으로, 그리고 슬라이드가 같이 보이는 환경에서 동영상 보기 원하시면 보기 좋은것 같애요.
예 좋은 링크 감사합니다.
구글쪽에서 한것도 있을겁니다. 그것도 보시면 좀 예제가 있어서 좋으실수도... 저는 jsconf.eu에서 한게 첫 발표라서 좋아하는 편입니다. ㅎㅎ
책의 저자셨군요!!!많이 보고 읽고 배우겠습니다.
나중에 뵙게되면 사인 부탁드립니다.
:)
예 감사합니다. 제 싸인이라도 괜찮으시다면 언제든지요. ^^;;;
사이트 가봤는데 직접 MVC 프레임웍을 만드시나봐요.
아 늦 모기 때문에 깼네요 -.-;;;
네 저희 프로젝트가 ExtJS 기반입니다만 페이지들 JS소스가 천줄이 기본인 바람에 적당한 MVC Framework를 찾아보았지만 직원들 다시 교육시키는 비용도 그렇고 현재 소스의 이행 문제도 있어서 바로 적용하기가 힘들더군요.
그러면 익숙한 Framework형식으로 만들어쓰는게 나을거 같아서 만들어보았습니다. 어쩌다보니 오픈소스로 전환한 상태이기도 합니다 :)
대단하시네요... 오픈소스까지...
프레임워크로 만들면서 정말 많이 배우셨겠네요.. ㅎㅎ 아~ ExtJS 하던 때가 생각나는군요. ㅎ
잘보고 갑니다.
node.js 이런것도 있군요!