기사 게재일:  2011 년 5 월 24 일 (출판일: 2011 년 8 월 02 일)

요약:  Node는 서버가 어떻게 작업해야 하는지에 대한 개념을 변화시킨 서버측 JavaScript 해석기입니다. 목표는 프로그래머가 고도로 확장 가능한 애플리케이션을 빌드하고 하나의 유일한 실제 머신만으로 수 만 개의 연결을 처리하는 코드를 쓰도록 사용하는 것입니다.


소개

Node에 대해 들어본 적이 있거나 node가 얼마나 대단한지 주장하는 기사를 읽어본 적이 있다면 "대체 Node.js가 무엇인가?"라고 궁금해할 수 있다. Node의 자체 홈 페이지를 읽은 후에도 Node가 무엇인지에 대해 여전히 의문을 가질 수도 있다. Node는 분명히 모든 프로그래머에게 맞는 것은 아니지만, 일부에게는 올바른 선택이 될 수도 있다.

이 기사는 Node.js가 해결하는 문제의 간단한 배경지식을 제공하여 Node. js가 무엇이고 어떻게 작업하며 간단한 애플리케이션을 실행하는 방법과 마지막으로 어디에서 Node가 훌륭한 솔루션인지에 대해 응답을 찾을 것이다. 이 기사는 복잡한 Node 애플리케이션을 쓰는 방법을 다루거나 Node에 대한 완전한 튜토리얼이 되지는 않을 것이다. 독자가 이 기사를 읽으면 자체적인 비즈니스에서 Node 학습을 더 심도있게 추구해야 하는지 여부를 결정하는 데 도움이 될 것이다.

Node가 어떤 문제를 해결하는가?

Node의 명시된 최우선 순위의 목표는 "확장 가능한 네트워크 프로그램을 빌드하기 위해 간편한 방법을 제공하는 것"이다. 현재 서버 프로그램의 문제는 무엇인가? 계산을 해보자. Java™ 및 PHP와 같은 언어에서 각 연결은 이와 함께 잠재적으로 수반하는 2MB 메모리가 있는 새 스레드를 생성한다. 8GB RAM을 갖춘 시스템에서 동시적 연결의 이론적인 최대 숫자로 약 4000명의 사용자를 연결시킨다. 클라이언트 기반이 성장하면서, 더 많은 사용자를 지원하는 웹 애플리케이션을 원했다면 점점 더 서버를 추가해야 했다. 물론, 이는 비즈니스의 서버 비용, 트래픽 비용, 인건비 및 기타 등등에 더해진다. 이러한 비용을 더하는 것은 잠재적인 기술 문제이다 — 사용자는 각 요청에 대해 다른 서버를 사용할 수 있으므로, 어느 공유 자원이나 모든 서버에 걸쳐서 공유되어야 한다. 이러한 모든 이유로 인해, 전체 웹 애플리케이션 아키텍처(트래픽 처리량, 프로세서 속도 및 메모리 속도 포함)에서 병목은 서버가 처리할 수 있는 동시 연결의 최대 숫자였다.

Node는 연결이 서버로 설정되는 방법을 변경하여 이 문제를 해결한다. 각 연결에 대해 새 OS 스레드를 생성하는(그리고 이와 수반하는 메모리를 할당하고) 대신에 각 연결은 Node 엔진의 프로세스 내에서 이벤트 실행을 촉발한다. Node는 허용된 잠금이 없고 I/O 호출에 대해 직접 차단하지 않기 때문에 교착 상태가 절대 없다고 주장한다. Node는 수 만개의 동시 연결을 지원할 수 있는 서버 실행을 주장한다.

그러므로 수 만개의 동시 연결을 처리할 수 있는 프로그램이 있으므로 Node로 실제로 무엇을 빌드할 수 있는가? 이 많은 연결에 필요한 웹 애플리케이션이 있다면 멋질 것이다. 이는 "이 문제가 있다면 문제가 아니다" 종류의 문제 중 하나이다. 이를 다루기 전에 Node가 어떻게 작업하는지 그리고 실행하도록 어떻게 설계되는지에 대해 살펴보자.

Node가 절대 아닌 것

그렇다. Node는 서버 문제이다. 하지만, 기본 Node 제품은 Apache 또는 Tomcat과 절대 같지 않다. 이러한 서버는 기본적으로 설치 준비된(ready-to-install) 서버 제품이고 앱을 즉시 배치할 준비가 되었다. 이러한 제품으로 바로 서버를 켜고 실행할 수 있다. Node는 절대 이러한 것은 아니다. Apache가 개발자들이 동적 웹 페이지를 작성하도록 허용하기 위해 PHP 모듈을 추가하고 안전한 연결을 위해 SSL 모듈을 추가할 수 있는 방법과 마찬가지로 Node는 Node 핵심에도 추가될 수 있는 모듈의 개념이 있다. Node로부터 선택하는 모듈은 그야말로 수 백 가지가 있고, 커뮤니티는 매일 많은 모듈을 제작하고 게시하며 업데이트하는 데 매우 활동적이다. 이 기사의 이후 부분에서 Node의 전체 모듈 부분에 대해 논의할 것이다.

Node가 작동하는 방법

Node는 그 자체로 V8 JavaScript를 실행한다. 잠깐, 뭐라고 했는가? 서버에서 JavaScript란 말인가? 그렇다. 독자가 제대로 읽었다. 서버측 JavaScript는 클라이언트에서 JavaScript로 독점적으로 작업한 모든 사람들에게 새로운 개념이 될 수 있지만, 그 생각 자체는 너무 멀리에서 도입한 것은 아니다 — 서버에서 사용하는 클라이언트의 동일한 프로그래밍 언어를 왜 사용하지 않는가?

V8은 무엇인가? V8 JavaScript 엔진은 Google이 Chrome 브라우저로 사용하는 내재된 JavaScript 엔진이다. 적은 수의 사람들이 클라이언트에서 JavaScript로 실제로 무엇이 발생하는지에 대해 생각한다. JavaScript 엔진은 실제로 코드를 해석하고 실행한다. V8을 통해 Google은 또 다른 고유한 측면으로 C++로 쓰여진 초고속 해석기를 제작했다. 이 엔진을 다운로드하고 원하는 어느 애플리케이션에나 임베드할 수 있다. 이는 브라우저에서 실행하도록 제한되지 않는다. 그러므로, Node는 실제로 Google이 쓴 V8 JavaScript 엔진을 사용하고 서버에서 사용하도록 용도를 변경한다. 완벽하다! 이미 훌륭한 솔루션이 사용 가능할 때 새로운 언어를 작성할 이유는 없다.

이벤트 구동형 프로그래밍

많은 프로그래머들은 오브젝트 지향 프로그래밍이 완벽한 프로그래밍 설계라고 생각하고 다른 것을 사용하지 않도록 교육받았다. Node는 이벤트 구동형 프로그래밍 모델이라는 것을 활용한다.


목록 1. jQuery로 클라이언트측에서 이벤트 구동형 프로그래밍
				
// jQuery code on the client-side showing how Event-Driven programming works

// When a button is pressed, an Event occurs - deal with it
// directly right here in an anonymous function, where all the
// necessary variables are present and can be referenced directly
$("#myButton").click(function(){
     if ($("#myTextField").val() != $(this).val())
         alert("Field must match button text");
});

서버측은 실제로 클라이언트측과 다르지 않다. 사실이다. 눌러야 하는 단추도 없고 입력하는 텍스트 필드도 없지만, 더 상위 레벨에서 이벤트가 진행 중이다. 하나의 연결이 작성되었다 — 이벤트이다! 데이터가 연결을 통해 수신된다 — 이벤트이다! 데이터가 연결을 통해 오는 것이 중지된다 — 이벤트이다!

이러한 유형의 설정이 Node에 이상적인 이유는 무엇인가? JavaScript는 익명의 함수와 클로저를 허용하고, 그리고 더 중요하게도 구문이 코드를 해 본 적이 있는 거의 모든 사람에게 익숙하므로 이벤트 구동형 프로그래밍에 훌륭한 언어이다. 이벤트가 발생할 때 호출되는 콜백 함수는 이벤트를 캡처하는 동일한 지점에서 쓰여질 수 있다. 코드하기에 간편하고 유지보수하기에도 간편하다. 복잡한 오브젝트 지향 프레임워크가 없고, 인터페이스도 없으며, 과도한 아키텍팅(over-architecting)이 없다. 이벤트를 청취하고 콜백 함수를 쓰기만 하면 모든 것이 처리된다!

예제 Node 애플리케이션

마침내 일부 코드를 살펴보자! 논의한 모든 것들을 한데 묶어서 첫 번째 Node 애플리케이션을 작성해보자. Node가 높은 트래픽 애플리케이션을 처리하는 데 이상적이라는 것을 확인했으므로 최대 속도를 위해 제작된 매우 간단한 웹 애플리케이션을 작성해보자. "상사"로부터 아래로 전달된 샘플 애플리케이션에 대한 스펙이 여기 나와 있다. 무작위 숫자 생성기 RESTful API를 작성한다. 애플리케이션은 하나의 입력, "숫자"라는 하나의 매개변수를 취해야 한다. 그러면 해당 애플리케이션은 0과 이 매개변수 사이의 무작위 숫자를 리턴하고, 생성된 숫자를 호출자에게 리턴할 것이다. 그리고, "상사"가 엄청나게 인기 있는 애플리케이션이 되도록 기대하고 있으므로 이는 50000명의 동시 사용자를 처리해야 한다. 다음 코드를 살펴보자.


목록 2. Node 무작위 숫자 생성기
				
// these modules need to be imported in order to use them.
// Node has several modules.  They are like any #include
// or import statement in other languages
var http = require("http");
var url = require("url");

// The most important line in any Node file.  This function
// does the actual process of creating the server.  Technically,
// Node tells the underlying operating system that whenever a
// connection is made, this particular callback function should be
// executed.  Since we're creating a web service with REST API,
// we want an HTTP server, which requires the http variable
// we created in the lines above.
// Finally, you can see that the callback method receives a 'request'
// and 'response' object automatically.  This should be familiar
// to any PHP or Java programmer.
http.createServer(function(request, response) {

     // The response needs to handle all the headers, and the return codes
     // These types of things are handled automatically in server programs
     // like Apache and Tomcat, but Node requires everything to be done yourself
     response.writeHead(200, {"Content-Type": "text/plain"});

     // Here is some unique-looking code.  This is how Node retrives
     // parameters passed in from client requests.  The url module
     // handles all these functions.  The parse function
     // deconstructs the URL, and places the query key-values in the
     // query object.  We can find the value for the "number" key
     // by referencing it directly - the beauty of JavaScript.
     var params = url.parse(request.url, true).query;
     var input = params.number;

     // These are the generic JavaScript methods that will create
     // our random number that gets passed back to the caller
     var numInput = new Number(input);
     var numOutput = new Number(Math.random() * numInput).toFixed(0);
     
     // Write the random number to response
     response.write(numOutput);
     
     // Node requires us to explicitly end this connection.  This is because
     // Node allows you to keep a connection open and pass data back and forth,
     // though that advanced topic isn't discussed in this article.
     response.end();

   // When we create the server, we have to explicitly connect the HTTP server to
   // a port.  Standard HTTP port is 80, so we'll connect it to that one.
}).listen(80);

// Output a String to the console once the server starts up, letting us know everything
// starts up correctly
console.log("Random Number Generator Running...");

이 애플리케이션 시작하기

"random.js"라는 파일로 위의 코드를 넣는다. 이제 이 애플리케이션을 시작하여 실행하기 위해(그러므로 HTTP 서버를 작성하고 포트 80에서 연결을 청취함) 명령 프롬프트에서 다음 명령을 간단히 실행한다. % node random.js 서버를 시작하여 실행하는 중임을 인식할 때 다음과 같이 표시될 것이다.

root@ubuntu:/home/moila/ws/mike# node random.js
Random Number Generator Running...

이 애플리케이션에 액세스하기

애플리케이션이 시작되어 실행 중이다. Node가 현재 어느 연결이나 청취하고 있으므로 애플리케이션을 테스트해보자. 간단한 RESTful API를 작성했으므로, 웹 브라우저를 사용하여 애플리케이션에 액세스할 수 있다. 다음 주소를 입력하자(이전 단계를 완료하도록 한다). http://localhost/?number=27

브라우저 창이 0과 27사이의 무작위 숫자로 변경될 것이다. 브라우저에서 다시 로드하기를 누르면 또 다른 무작위 숫자가 나타날 것이다. 이렇게만 하면 된다. 첫 번째 Node 애플리케이션이 나왔다.

Node가 무엇에 유용한가?

자, Node에 대해 모두 읽고 나서 "Node란 무엇인가?"라는 질문에 응답할 수 있지만, "Node를 무엇에 대해 사용해야 하는가?"라는 의문을 가질 수 있다. Node가 정말로 유용한 것이 있기 때문에 이는 물어볼 만한 중요한 질문이다.

유용한 것

지금까지 살펴본 것처럼 Node는 대량의 트래픽과 서버측 논리를 예상하는 상황에 극도로 우수하게 설계되었고, 필요한 처리는 클라이언트에 응답하기 전에 반드시 규모가 클 필요는 없다. 여기에 Node가 탁월한 훌륭한 예제가 나와 있다.

  • RESTful API

    RESTful API를 제공하는 웹 서비스는 몇 가지 매개변수에서 취하고 이를 해석하여 응답과 함께 묶고 응답(대개 상대적으로 적은 양의 텍스트)을 사용자에게 다시 보낸다. 이는 Node에 이상적인 상황이다. 왜냐하면 이는 수 만개의 연결을 처리하도록 제작될 수 있기 때문이다. 이는 또한 대용량의 논리를 요구하지 않고, 기본적으로 데이터베이스로부터 값을 찾아 응답과 함께 종합한다. 응답이 소규모의 텍스트이므로, 수신 요청은 소규모의 텍스트이고, 트래픽 볼륨은 높지 않고, 하나의 머신이 가장 바쁜 회사의 API의 API 요청조차 처리할 가능성이 높다.

  • Twitter 큐

    트윗을 수신하고 데이터베이스로 이를 써야 하는 Twitter와 같은 회사에 대해 생각해 보자. 그야말로 초당 수 천개의 트윗이 들어오고 데이터베이스는 최대 사용 시간 동안 필요한 쓰기의 수를 거의 유지할 수 없다. Node는 이러한 문제점에 솔루션에서 중요한 구성요소가 된다. 확인한 대로 Node는 수 만개의 수신 트윗을 처리할 수 있다. 그러면 이는 인메모리 큐잉 메커니즘(예를 들어, memcached)으로 이를 빠르고 간편하게 쓸 수 있으며, 여기에서부터 또 다른 별도의 프로세스가 해당 데이터베이스로 이를 쓸 수 있다. 여기에서 Node의 역할은 트윗을 빠르게 수집하고 정보를 쓸 책임이 있는 다른 프로세스로 전달하는 것이다. 또 다른 설계를 상상해보자 — DB 자체로 쓰기를 처리하기 위해 노력하는 정상 PHP 서버 — 모든 트윗은 DB 호출이 차단되었으므로 DB에 쓰인 대로 약간의 지연이 발생할 것이다. 이러한 설계를 갖춘 머신은 데이터베이스 대기 시간으로 인해 초당 2000개의 수신 트윗만 처리할 수 있다. 초당 백 만개의 트윗이고 500개의 서버를 말하는 것이다. 그 대신에 Node는 모든 연결을 처리하고 차단하지 않아 이에 발생할 수 있는 가능한 많은 트윗을 캡처하기 위해 사용한다. 한 개의 노드 머신은 초당 50000개의 트윗을 처리할 수 있으며, 20개의 서버만 말하는 것이다.

  • 비디오 게임 통계

    Call of Duty 온라인과 같은 게임을 해본 적이 있다면, 게임 통계를 살펴볼 때 주로 통계의 레벨을 제작하기 위해 게임에 대해 엄청난 정보를 추적해야 한다는 생각이 즉시 떠오른다. 그러면 어느 시점에나 게임을 하는 수 백만의 사람들을 고려하면, 매우 빠르게 생성되는 수많은 정보가 있음을 깨닫는다. 게임으로부터 생성되는 데이터를 캡처할 수 있고, 이에 통합의 최소량을 수행한 다음에 데이터베이스로 쓰기 위해 이를 큐할 수 있기 때문에 Node는 이 시나리오에 대해 훌륭한 솔루션이다. 게임에서 사람들이 얼마나 많은 총알을 발사하는지 추적하는 데 전체 서버가 전념하는 것은 우스워 보일 수 있다. 이는 Apache와 같은 서버를 사용한 경우에 유용한 한계가 될 수 있지만 Node를 실행 중인 서버로 작업할 수 있는 것과 같이 게임에서부터 거의 모든 통계를 추적하는 데 하나의 서버가 전념할 수 있었다면 덜 우스워 보일 것이다.

Node 모듈

이 기사에서 원래는 계획된 논의가 아니었지만 대중적인 요청으로 인해 Node Modules과 Node Package Manager의 간략한 소개를 포함하도록 늘렸다. Apache로 작업하는 것에 익숙해지면서 성장한 사람들처럼 독자는 모듈을 설치하여 Node의 기능을 확장할 수 있다. 하지만, Node로 사용할 수 있는 모듈이 해당 제품을 엄청나게 향상시키기 때문에, 누구나 몇 가지 모듈을 설치하지 않고 Node를 사용할 가능성은 낮다. 이는 모듈이 전체 제품의 필수적인 부분이 되기까지 훌륭해진 이유이다.

참고자료에서 필자는 모듈 페이지로 링크를 제공하며, 여기에 모든 가능한 모듈이 나열되고 다운로드 가능하다. 기회를 빠르게 추출하기 위해 이는 사용 가능한 수많은 모듈 가운데 동적으로 작성된 페이지(PHP 등)를 쓰기 위한 모듈, MySQL로 간편하게 작업하기 위한 모듈, WebSockets를 돕기 위한 모듈 및 텍스트와 매개변수 구문 분석을 지원하기 위한 모듈을 포함한다. 필자는 모듈의 세부사항을 다루지 않을 것이다. 다시 말하지만, 이 기사는 Node를 심화하여 추구해야 할 만한 것인지 이해하는 데 도움을 주는 개요 기사에 불과하기 때문에, 독자가 이를 심도있게 알아보려고 선택하는 경우 당연히 사용 가능한 모듈로 작업해야 할 것이다.

추가적으로, Node는 Node Package Module을 갖추고 있으며, 이는 사용 중인 Node 모듈을 설치하고 관리하는 내장형 방식이다. 이는 자동으로 종속 항목을 처리하므로 설치하려는 어느 모듈이나 모든 필수 조각으로 제대로 설치하는 것이 보장될 수 있다. 자체적인 모듈에 관여하여 쓰려고 선택하는 경우 이는 Node 커뮤니티로 자체적인 모듈을 게시하는 방법으로서 역할을 담당한다. Node 설치를 중단하는 것에 대해 걱정하지 않고 Node의 기능을 간편하게 확장하는 방법으로서 NPM을 고려해보자. 다시 말하지만, Node를 심도있게 추구하기 위해 선택하는 경우 NPM은 Node 솔루션의 필수적 부분이 될 것이다.

결론

편집자의 참고

이 기사의 초기 발표된 버전으로 인해 이 기사가 표현한 다양한 관점에 대해 커뮤니티에서 많은 논의가 생성되었다. 그 이후로 작성자는 이러한 생각을 염두에 두고 이 기사를 개정했다. 이러한 종류의 동료 검토와 논의는 오프 소스 영역의 필수적인 부분이다. 건설적인 조언을 제공한 사람들한테 감사한다.

모든 오픈 소스 프로젝트와 마찬가지로 Node.js는 계속 진화할 것이고 개발자들은 한계의 숫자를 막론하고 이를 극복하기 위해 새로운 자원과 기술을 발견할 것이다. 언제나처럼 독자들이 스스로를 위해 기술을 시도해 보기 바란다.

"Node.js란?"이라는 이 기사의 초반부에서 독자가 가졌던 많은 의문들에 대해 이 기사를 읽은 후에 독자 스스로 모두 답할 수 있어야 한다. 독자는 Node.js가 무엇인지에 대해 몇 가지 분명하고 간결한 문장으로 설명할 수 있어야 한다. 그렇게 수행할 수 있다면, 거의 다른 모든 프로그래머들보다 앞서는 것이다. Node에 대해 필자와 대화했던 많은 사람들이 Node가 정확하게 수행하는 내용에 대해 혼란스러워했다. 당연히 이들은 Apache 사고방식을 가지고 있다 —서버가 HTML 파일을 놓는 애플리케이션이고 모두 작동한다는 것이다. 대부분의 프로그래머가 Apache와 Apache가 작업하는 것에 익숙하기 때문에, Node를 설명하는 가장 간편한 방법은 Apache와 비교하는 것이다. Node는 Apache가 할 수 있는 어느 작업이나 할 수 있는(일부 모듈을 사용하여) 프로그램이지만, 빌드할 수 있는 확장 가능한 JavaScript 플랫폼이 되어 훨씬 더 많은 작업을 할 수도 있다.

이 기사에서 Node가 고도로 확장 가능한 서버를 제공하는 목표를 달성하는 방법을 확인했다. 이는 Google, V8 엔진으로부터 엄청나게 빠른 JavaScript 엔진을 사용한다. 이는 코드를 최소화하고 읽기 간편하게 유지하도록 이벤트 구동형 설계를 사용한다. 이러한 모든 요인들로 인해 Node가 원하는 목표를 만들어낸다 — 이는 엄청나게 확장 가능한 솔루션을 쓰기에 상대적으로 간편하다.

Node가 무엇인지에 대해 이해하는 것이 중요한 것처럼 무엇이 아닌지에 대해 이해하는 것도 중요하다. Node는 즉시 PHP 웹 애플리케이션을 더 확장 가능하게 만들 Apache의 대체물에 불과하지 않다. 그것은 전혀 사실이 아니다. 지금은 Node의 수명 중에서 여전히 초기 단계이지만, 엄청나게 급격히 성장하고 있으며 해당 커뮤니티가 매우 적극적으로 관여하고, 작성되는 훌륭한 모듈이 매우 많고 이렇게 성장하는 제품은 독자의 비즈니스에 1년 내에 나타날 수 있다.


참고자료

교육

제품 및 기술 얻기

토론


출처 - http://www.ibm.com/developerworks/kr/library/os-nodejs/




'Framework & Platform > Node.js' 카테고리의 다른 글

node.js - npm 1.0 사용하기  (0) 2012.07.16
node.js - socket.io 소개  (0) 2012.07.12
node.js - CentOS에서 설치(install in linux)  (0) 2012.07.03
node.js - 소개 3  (0) 2012.06.07
node.js - 소개  (0) 2012.06.07
Posted by linuxism
,