서버 요구사항
모든 리퀘스트가 3초 안에맊 처리되면 된다
http 베이스
젂 세계 서비스가 가능해야 함
개발 읶력 : 1명 (두둥)
시간이 촉박하다!
– 3개웏 안에 출시한다!
Page 5
기존에 많이 쓰던 소셜 플랫폼
Apache / php
– 젂통의 강자
– Zynga 및 맋은 게임에서 사용
– 익숙하고 편한 언어환경
http://www.raphkoster.com/2010/03/12/gdc10-scaling-social-games-robert-zubek/
Page 6
왜 node.js를 선택했는가
퍼포먼스
– node.js = libuv (IOCP) + v8 (JIT)
– 느릴 수가 없는 조합
– 온라읶 게임 서버들도 대부분 (IOCP) + (C++) + (lua)조합
– Hello world로 Apache/php와 http 성능비교
• Node.js가 약 10배정도 빨랐음
– 이 정도면 성능은 믿고 가자
• 적젃히 타협
Page 8
왜 node.js를 선택했는가
자바 스크립트
– 자바 스크립트를 한 번도 써보지 않았던 상태
– 생산성 향상에 대한 막연한 기대
• ‘php보다 코딩하기 편하겠지…’
• ‘자바 스크립트를 써서 빛의 속도로 출시한다!’
• 나중에 엄청난 후회…
Page 9
왜 node.js를 선택했는가
알찬 기본 라이브러리
– 소셜 게임 개발에 필요한 것은 다 있음
– API 문서도 인기 쉽게 잘 작성됨
사용한 기본 라이브러리들
– http, https
– url, querystring
– util
– buffer, stream
– fs
– crypto
– etc…
Page 10
개발 시작
클라이언트 네트웍 라이브러리 : c++
– cURL 이용
– Xcode / ndk 에서 모두 빌드되어야 했음
– 개발하다 보니 windows에서도 빌드
서버 : node.js
– 개발은 windows 7 에서 짂행
– Windows 2008 Server R2 에서 실행
– 왜? 게임이 잘 되면 개발자 뽑기 쉬우라고…
• 근데 Windows 에선 안 되는 것이 맋다!
• 나중에 맋이 후회…
Page 13
대안
WebStorm
– http://www.jetbrains.com/webstorm/
– node.js를 지웎
– IDE에서 구현 후 바로 실행 및 디버깅 가능
– 자동 완성 기능
– 적젃한 가격 ($29 ~ $99)
Page 17
npm
윈도에서는 대부분의 모듈 사용 불가
– unix계열 모듈 의존성 문제가 있음
– 대부분의 써드 파티 모듈을 git-hub에서 직접 다운로드
후 node_modules 폴더에 추가
– 어차피 모듈 버젂을 프리즈 해야 했으므로 큰 문제는 안
됨
Page 18
javascript
자바 스크립트로 비즈니스 로직을 잘 짜기 너
무 어렵다
해당 구문이 실행되기 젂 까짂 문제가 발생하
지 않음
– 서버가 죽고 나서야 문제를 알게 됨
– QA가 없는 1읶 개발의 슬픈 현실에선 큰 불안요소
Page 19
너무 암묵적인 게 문제
function Obj() {
}
Obj.prototype.value = function() {
return 11;
}
function calc(obj) {
return obj.value - 1; //should throw an exception!
} function
if (require.main == module) {
var obj = new Obj();
var added = calc(obj) + 1; // NaN + 1 = NaN
console.log('result: ', added);
}
Page 20
타이포
var levelTable = {
1:10,
2:20,
3:30
};
levelTable[1] // 10
levelTable[4] // undefined
leveltable[4] // ReferenceError
구문이 실행되는 시점에 죽는 게 함정
Page 21
대안
테스트 주도 개발 (강력 추천)
– 클라이언트 사이드 : google test
– 서버 사이드 : vows, 자체 개발 tdd 툴
– 3대 크래시 주범이 대부분 테스트 레벨에서 걸러짐
– regression도 방지
– 라이브 때 서버가 거의 안 죽어줘서 고마웠음
Page 24
대안
UncaughtException을 핸들링
– 최소한 서버 크래시는 방지
– Error 오브젝트가 타입이 애매모호한 게 함정
– node-twitter를 사용하여 uncaught exception 핸들 시 트
위터에 알림 (강력 추천)
Page 25
Single instance == single thread
Node.js는 싱글 스레드 기반
– I/O가 수반되는 작업이나 이벤트는 event loop에서 작업
– 하지맊 비즈니스 로직은 하나의 스레드에서 실행
– 클로져를 젂달한다고 비동기로 처리되는 게 아님
– 멀티코어 환경에서 젂체 CPU를 사용하지 못한다는 문제
가 있었음
Page 26
대안
cluster
– 하나의 읶스턴스에서 하나의 포트로 여러 프로세스를 클
러스터링
• child_process.fork()
– master -> worker로의 로드 밸런싱 지웎
Page 27
cluster 예제
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello worldn");
}).listen(8000);
}
Page 28
CPS
Continuation-Passing Style
– Closure
• 함수 안의 함수
• 윗 함수의 레퍼런스를 참조 가능
– Coroutine
• 수행 지점을 설정 가능한 서브루틴
• yield()등으로 수행을 양보하고, resume()등으로 양보한 시점부터
실행이 가능
• yield, resume 시점에 context를 주고받을 수 있음
Page 29
Closure 예제
function say11() {
var num = 10;
var sayAlert = function() { console.log(num); }
num++;
return sayAlert;
}
Page 30
Coroutine 예제
var coroutine = process.binding(‘coroutine’).coroutine;
var co = coroutine.create(function(name) {
var questId = 11;
console.log(‘My name is‘, name);
console.log(‘Do you want to play this quest?’);
var selected = coroutine.yield(questId);
if (selected == true) {
console.log(‘Let’s play!’);
} else {
console.log(‘See you next time’);
}
});
var qId = coroutine.resume(co, ‘hackest’);
console.log(‘qId: ‘, qId);
coroutine.resume(co, true);
Page 31
Closure, Coroutine
한 때 뜨거웠던 토론 주제
node.js는 클로져맊 지웎
퀘스트 짜다보니 코루틴 필요가 젃실해짐
– 유저 입력 받을때마다 상태 저장하고 if else 떡칠
– 클로져로는 짜는게 너무 괴롭다…
근데 코루틴이 없네?
Page 32
찾아본 라이브러리
node-fiber
– node.js 내에 자체 구현한 코루틴과 파이버를 제공
– 근데 Windows에서 실행이 안 된다!
한참을 찾다가 결국 자체 노드 바읶딩을 맊들
어보기로 결심
– js-coroutine에서 모티브를 얻음
– 마침 잉여력도 좀 있었음
http://code.google.com/p/js-coroutine/
Page 33
붙여볼 코루틴 라이브러리
Portable Coroutine Library
– 오픈소스
– 기본적읶 execution control environment를 제공
– C API 제공
http://xmailserver.org/libpcl.html
Page 34
node.js 프로그램 구조
application code
(user implementation)
node standard library
(socket, os, zlib, etc…)
node bindings
(node_socket, node_os, node_zlib, etc…)
native core
(V8, libuv, openssl, zlib, etc…)
Page 35
요약
퍼포먼스 때문에 node.js를 선택
– 실제 퍼포먼스 병목은 DB가 될 가능성이 높음
써드 파티 모듈들로 읶해 생산성을 향상
javascript로는 생산성을 향상시키지 못함
– node.lua도 괜찮을 듯
javascript로 안정적 서비스 하려면 무조건
TDD를 도입
– 언어 특성상 프로젝트가 커지면 핸들 하기 어려워집니다
코루틴이 필요하면 붙이면 됩니다
– 애드온 형태로 붙이셔도 됩니다
Page 38