본문 바로가기

Programing/Node.js

[Node.js] - 윈도우 지원의 역사

전에 유투브에서 Node.js를 만든 Ryan Dahl이 "윈도우는 매우 중요하다. php처럼"이라는 말을 진지하게 했다가 사람들은 농담인지 알고 웃었던 장면을 본적이 있다. (아래 동영상에서 52초 부근~1:20초)


node.js가 v0.10.21이 나오도록 아래 아키텍처 그림은 계속 검색이 된다.


하지만 Node.js는 v0.5부터 획기적인 변화가 있었다.

2011년 5월 5일 (어린이날!)에 발표한 로드맵 문서(http://nodejs.org/nodeconf.pdf)를 보면

v0.5의 주요 목표는 윈도우 호환성이었다!!!


윈도우로의 포팅이 왜 중요한지는,

서버의 33%가 윈도우이고, 웹 브라우저의 87%가 윈도우에서 돌아가고 있다는 것이다.(지금은 모바일 %가 높아졌지만)


이전까지는 윈도우에서 노드제이에스를 돌리기 위해서는 Cygwin이라는 윈도우에서 리눅스를 비스므래하게 쓸 수 있는 환경이다. 그런데 시그윈은 완전히 *nix계열을 지원하지 않은 뿐만 아니라 설치의 번거로움과 버그들도 있고 무엇보다 느리다는 문제가 있다.


0.5가 되기 전까지는 Node.js는 liberio와 libev라이브러리를 이용해서 *nix계열의 비동기 I/O를 처리를 했다.

문제는 이런 라이브러리들은 kqueue나 epoll같은 것들을 사용하게 되는데 윈도우에서는 이런 시스템 콜이 아예 없기 때문에 select와 같은 POSIX라이브러리를 사용하게 된다. 문제는 윈도우로 포팅된 select()는 100개 이상에 대한 처리부터 현저하게 느려지는 단점을 가지고 있다는 것이다. 왜냐하면 커널이 이용할 수 있는 데이터가 있는지 어떤지를 판별하기 위해서 내부적으로 모든 소켓을 조사해야 하기 때문이다. 또한 Win32 API로 포팅된 WSAEventSelct()가 대안이긴 하지만, 동기화 함수인 WSAWaitForMultipleEvents()가 한 쓰레드에서 64개까지 모니터링 할 수 없기 때문에 문제가 된다.

(WSA_MAXIMUM_WAIT_EVENTS라는 이름으로 define된 값이 64이다!)


이런 문제는 비단 Node.js뿐만 아니라 Nginx에서도 볼 수 있는데, nginx for Windows를 보면,

Version of nginx for Windows uses the native Win32 API (not the Cygwin emulation layer). Only the select()connection processing method is currently used, so high performance and scalability should not be expected. 

(윈도우를 위한 nginx버전은 (Cygwin 에뮬레이션 계층이 아닌) 네이티브 Win32 API를 사용합니다. (하지만) select()를 이용한 연결처리를 현재 사용하고 있기 때문에, 높은 성능과 확장성은 기대할 수 없습니다.

라고 되어있다.

또한 이전부터 미래에 향상을 위해 할지 모를 목록에 보면,

Possible future enhancements
미래에 향상시킬지도...

  • Running as a service.
  • Using the I/O completion ports as a connection processing method.
    (I/O completion ports를 이용한 연결 처리 방식)
  • Using multiple worker threads inside a single worker process.

가 있는데 이것이 언제 될지 알 수 없는 노릇이다.


그래서 libev와 libevent는 대안이 될 수 없고 부스트의 비동기 IO역시 방대함에 문제가 있다는 것이다.

(아래 슬라이드에 대해서 Ryan Dahl이 Asynchronous I/O in Windows for Unix Programmers라는 이름의 글을 썼다.)

 그래서 나오게 된 새로운 아키텍처는 아래와 같다.

일종의 libeio라는 중간 계층을 두어서 iocp를 지원하겠다는 전략인 셈이다.


libol이라는 이름이 기존 오픈소스프로젝트(Library for Online Learning algorithms)와 이름이 겹쳐서 그런지 결국 0.5의 라이브러리의 이름은 libuv가 되었다.


Node.js의 윈도우 지원의 역사를 요약하면 아래와 같다.

2011.01.23 (목) Joyent와 Microsoft가 파트너쉽을 맺게 되면서 Node를 윈도우로 포팅에 공헌하겠다고 공식적으로 언급을 했다. 주요 사항은 고-성능 IOCP API였다. (링크)

2011.03.13 libuv를 node 빌드 시스템에 통합 (관련코드이슈 / 소스코드브라우저(libev-,uv+) <~ 그 이전 )

2011.09.23 (금) Node를 Windows로 포팅의 결과 새로운 플랫폼 라이브러인 libuv를 사용하게 되었다. (링크)

2012.07.20 v0.9.0 버전부터 libuv에 포함되어 있던 libev가 제거하였다. (링크 / 관련코드이슈)