빠르게훓어보는 Node.js와 Vert.x
-
Upload
terry-cho -
Category
Engineering
-
view
5.587 -
download
6
Transcript of 빠르게훓어보는 Node.js와 Vert.x
빠르게 훑어 보는 node.js 와 Vert.x
조대협http://bcho.tistory.com
VS
소개
조대협 ( 조병욱 )
• 벤처 개발자• BEA 웹로직 기술 지원 엔지니어• 오라클 장애 진단 , 성능 튜닝• NHN 잠깐• 오라클 컨설턴트 (SOA,EAI,ALM,Enterprise 2.0)• 오라클 아키텍트 ( 대용량 분산 시스템 )• MS APAC 클라우드 수석 아키텍트• 프리렌서 ( 좋은 말로 사장님 )• 지금은 어느 회사의 Chief(Cheap?) 아키텍트
블로그 : http://bcho.tistory.com이메일 : [email protected]페이스북 ServerSideArchitectGrouphttps://www.facebook.com/groups/serverside/
오늘은 ?
1.빠르게 훑어 보는 Node.js2.Node.js 와 유사한 Vert.x
들여다 보기3.Node.js 와 Vert.x 비교하기
1. 빠르게 훑어 보는 node.js
Node.js 는 ?• 자바 스크립트를 이용한 고성능 서버 프로토 타입
– 구글 크롬 V8 자바스크립트 엔진 사용– CommonJS 기반– 싱글 쓰레드 모델– 비동기 / 논 블록킹 IO 기반– 빠른 생산성 , 아직은 비완성체
• 그런데 왜 ?– 게임– 높은 생산성 – 쉽다– SOCKET.IO 푸쉬– 레퍼런스
• 야머 , 링크드인 , 페이팔
Node.js 의 내부구조• 내부 구조
Node.js 의 내부구조• ELP (Event Loop)
socket fd = array[ 연결된 socket connec-tions]for(int i=0;i<fd.length;i++){if(fd 가 이벤트가 있으면 ){ 알고리즘 처리}// if}// if
epoll,kqueue,dev/poll,select,iocp
Node.js 의 내부구조• Single Thread Model
멀티 쓰레드 싱글 쓰레드 (Node.JS)
CPU Intensive 한 작업이 많으면 다른 request 처리가 줄줄이 밀림 무거운 로직을 돌리기에는 적절하지 않음
Node.js 의 내부구조• 보통 서버는 (Blocking Call)
Source : http://blog.cloudfoundry.com/2012/06/27/future-proofing-your-apps-cloud-foundry-and-node-js/
Node.js 의 내부구조• 그런데 , node.js 는 ? Async/Non-Blocking
http://strongloop.com/strongblog/node-js-is-faster-than-java/
Node.js 의 내부구조• Non blocking/Async IO
동기식 IO 비동기식 IO(node.js)
• 커피 주문하고 기다리기 • 커피 주문하고 진동벨 받기
동시 처리할 수 있는 사용자 수 = 쓰레드 수 ※ 동시 접속이 많은 시스템 ( 채팅 , 게임 ) 에 불리함
Node.js 의 내부구조• Node.JS 의 Thread Pool
– OS 에 따라 , 일부 IO 는 NonBlocking IO 를 제공하지 않음– 이 경우 자체 Thread Pool 을 이용하여 , Non-Blocking IO 인 것
처럼 Async 처리 해줌
그럼 성능은 ?• Node.JS 가 항상 빠른 것은 아님 ..!!
Servlet + RESIN + MYSQL
Node.JS + MYSQL
http://www.techempower.com/benchmarks/#section=data-r8&hw=i7&test=query
어디다 써먹나 ?• 빠른 Prototype 개발• Socket.IO 를 이용한 Push 처리• File Up/Download 같이 동시 연결수가 많고 , IO Inten-
sive 한 네트워크 스트리밍• 간단한 Single Page App
Node.JS 주요 모듈• 모듈
분류 모듈명
웹 MVC Express
REST API Express
Socket IO Socket.IO
인증 / 인가 Pass Port
데이타베이스 MySQL Native,Redis Native, Mongoose, Mongo-Native
로깅 Winston
단위 테스트 Mocha
설치 , 배포 npm
서버 기동 Forever
빌드 스크립트 grunt
Node.JS 주요 모듈• NPM
• npm install {module}• npm update {mod-
ule}• npm remove {mod-
ule}• npm info {module}cf. Linux rpm
• package.json
※ C/C++ 기반의 Native module 인 경우 컴파일러가 필요함
{ "name": "app", "version": "0.0.1", "dependencies": { "express": "3.x", "redis": "*"}“repository”: {“type”:”git”,”url”,”git://xxxx”}
cf. java maven pom.xml
Express• 웹 애플리케이션 개발 프레임웍• REST API 지원• Session,Cookie 일반적인 웹 기능 모두 지원• Redis 를 이용한 Session Clustering 지원• node.js 의 대세 !!※ MEAN STACK (MongoDB + Express + AngularJS + Node.js) – CF. LAMP
Express• Router
/app.js(main)
/index.js(route module)
• function index(req,res)• function home(req,res)
/user.js(route module)
• function list(req,res)• function add(req,res)
HTTP GET/
HTTP GET /usersHTTP POST /users
Express• Event Loop in Express
• REST API
Input{ name:’Terry’,address:’Seoul’}
Output{ result :’success’}
Express• Template
Router (business logic)
+
Template (view)
• hogan.js (4257ms)• ejs (5283 ms)• jade - same author who made ejb. (13068ms)※ Performance comparison https://github.com/Deathspike/template-benchmark
• Template Engines [engine name (100,000 template rendering time ms)]
Express• REST API
Input{ name:’Terry’,address:’Seoul’}
Output{ result :’success’}
MongoDB• MongoDB
– NoSQL (RDB Like – Index, Grouping, Sorting etc)– Document base (Store JSON)
Command SQL MongoDB
Insert insert into users ("name","city") val-ues("terry","seoul")
db.users.insert({_id:"terry",city:"seoul"})
Select select * from users where id="terry" db.users.find({_id:"terry"})
Update update users set city="busan" where _id="terry"
db.users.update( {_id:"terry"}, {$set :{ city:"Busan" } } )
Delete delete from users where _id="terry" db.users.remove({_id:"terry"})
MongoDB• MongoDB in node.js
– MongoNative (JDBC in Java)• Support Connection Pooling/Async IO
MongoDB• MongoDB in node.js
– Mongoose (Object Data Mapper – ODM)• Scheme base• Data validation• Support Connection Pooling/Async IO
Scheme
Validator
Model
MySQL• MySQL in node.js
– MySQL Native module• Support Connection Pooling/Async IO
Socket.IO• Web push method
1. AJAX (Comet)
upgrade
2. Web Socket– Similar to Streaming– Start from ws:// (not http://)
Socket.IO• Socket.IO is
– Abstract WebSocket, FlashSocket, AJAX Long Polling, AJAX Multi part Streaming, IFrame, JSONP Polling
• Why?
Source : http://caniuse.com
• Node.JS module• Different supportability
in browser. • Socket.IO supports web
push with various mechanism
Socket.IO• Server
Socket.IO• Client
Socket.IO• 이벤트 보내고 받기
– 이벤트 보내기 : socket.emit(“ 이벤트명” ,{ 메세지 });– 이벤트 받기 : socket.on(“ 이벤트명” ,function(data){});– 나를 제외한 클라이언트들에게 이벤트 보내기
socket.broadcast.emit(“ 이벤트명” ,{ 메세지 });– 나를 포함한 모든 클라이언트들에게 이벤트 보내기
io.socket.emit(“ 이벤트명” ,function(data){});– 다른 특정 소켓에 메세지 보내기
io.socket( 소켓 ID).emit(“ 이벤트명” ,{ 메세지 });
• 소켓에 데이타 바인딩– 저장 : socket.set(“ 키” ,” 값” ,function(){});– 가져오기 : socket.get(“ 키” ,function(err,value){});– 지우기 : socket.del(“ 키” , function(err,value){});
• 현재 소켓의 ID 가져오기– socket.id
Socket.IO• ROOM ( 채널 )
– 채널 조인하기 : socket.join(“ 룸이름” )– 채널에서 나오기 : socket.leave(“ 룸이름” );– 룸안에 있는 소켓에 이벤트 보내기
io.sockets.in(“ 룸이름” ).emit(“ 이벤트” ,{ 메세지 });– 룸안에 있는 나를 제외한 소켓에 메세지 보내기
socket.brodcast.to(“ 룸이름” ).emit(“ 이벤트” ,{ 메세지 });– 현재 생성되어 있는 룸 이름 읽어오기
io.sockets.manager.rooms– 룸안에 있는 소켓 목록 리턴
io.sockets.client(“ 룸이름” );
Socket.IO• 클러스터 구성
node.js node.js node.js
redis
Browser Browser Browser Browser
socket.iopub sub sub sub
redis channel : ‘dispatch’
haproxy
– Socket.IO 정보는 기본적으로 로컬 메모리에 저장됨– 클러스터 ( 멀티 노드 ) 사용시 Redis 를 사용하면 알아서 노드간
공유됨• Just change session store to redis
비동기 코딩 패턴Serial Sequence PatternSync Code
Parallel pattern
CALLBACK HELL !!
비동기 코딩 패턴• Async 프레임웍을 이용한 단순화
– 흐름 제어 • Serial : 순차 실행• Parallel : 병렬 실행• Waterfall : 순차 실행 , 전단계의 결과를 다음 단계로 넘김
Node.JS 는 잘 죽는다 .• V8 엔진 Memory Leak• Catch 가 안되는 에러가 나면 죽어버린다• 해결책 1. – 다시 스타트
– forever– Supervisor ( 코드 변경시 자동 재시작 )– nodemon ( 코드 변경시 자동 재시작 )– PM2
• 해결책 2. – process.on(‘uncaughtException’, )– 죽을때 무슨 원인으로 죽었는지를 모른다 . – domainAPI 를 사용한다 .
※ http://www.slideshare.net/domenicdenicola/domains-20010482
단위 테스트• Mocha test framework
– 자바스크립트 테스트 프레임웍 ( 웹 /node.js 지원 )– TDD 와 BDD 양쪽 지원
TDD BDD
LanguageassertEquals(count,5)프로그래밍 언어에 가까움
$(count).should_be(5)인간 언어에 가까움
테스트 케이스 개발
Spec Coding Test Coding
Spec Test Coding
테스트 대상 단위 ( 함수 ) 를 테스트 기능 ( 시나리오 ) 을 테스트
Clustering• Clustering Module
– 하나의 Machine 에서 여러개의 Node.js 인스턴스를 띄울 수 있음– 같은 포트로 Listen※ 굳이 그래야 하나 ? 어짜피 로드밸런서를 둬야 하는데
• 다른 Cluster 구성– Cluster 모듈 없이 앞단에 Reverse Proxy (LB) 배치– Session, Socket.IO Sharing 은 Redis 로
모니터링 툴• Appdyanmics
연계 시스템간의 성능 모니터링 가능 코드별 수행 시간 추적 가능
모니터링 툴• NewRelic Nodetime ( 얼마전에 AppDyamics 에
인수됨 )– 1 노드 모니터링 무료
구간별 소요시간 분석 가능
기타 눈여겨 볼만한 모듈• Passport : 인증 모듈 , 소셜 인증 ,Oauth,OpenID 등 인증등 제공• Winstone : 로깅 모듈
2. Vert.x 에 대한 간략한 소개
Vert.x 는• Overview
– JVM 위에서 동작– 고성능 네트워크 IO 서버인 Netty 를 기반– Hazlecast (IMDG) 를 이용한 데이타 버스– 뒷단은 비동기 IO 가 아니라서 Thread Pool 을 이용한 비동기 IO
시뮬레이션 처리– 동작 구조는 Single Thread ( 멀티 쓰레드 지원 *)– Polyglot ( Java,Javascript,Python,Groovy,Scala 지원 )– 다른 자바 서버에 Embedding 이 가능함 (Tomcat 과 같은 서버에 em-
bed 해서 돌릴 수 있음 )JavaJavaScript
Python
Groovy
Scala
Netty
Polyglot Event Bus
(Hazel-cast)
Worker Thread
Pool
JVM
Vert.x 개념 잡기• Verticle
– node.JS 의 하나의 route 모듈과 같은 개념 (Servlet)– 독립적인 ClassLoader 에 의해 로딩됨 (Isolation 됨 )
: 다른 Verticle 과 공유되지 않기 때문에 , 멀티 쓰레딩을 신경 쓸 필요가 없음
Vert.x 개념 잡기• Worker Verticle
– EventBus 를 통해서 오는 작업을 뒷단에서 비동기 처리– Thread Pool 을 사용함
Vert.x 개념 잡기• Event Bus
– HazleCast 기반의 메세지 큐 (cf. node.js Redis)– 다른 서버로 이벤트가 들어오더라도 , HazelCast 에 의해서 해당
event handler 가 있는 서버로 이벤트를 라우팅 해줌
Vert.x 개념 잡기• Vert.x Instance
– 하나의 JVM Process– 동시에 여러개의 Verticle 을
수행할 수 있음– 동시에 여러개의 Event Loop
Thread 를 수행할 수 있음
Vert.x 개념 잡기• Socket.IO, Pumping (node.js 의 Pipe) 등 node 의
기본 주요 기능은 대부분 제공함• DB 나 FILE IO 는 Non blocking IO 라이브러리가 없음
(Thread Pool 로 Async 처리만 함 )• HA 기능 제공
– Vert.x Instance 가 죽으면 다른 머신에서 자동 RE-START
주의 사항• JVM 기반이기 때문에 GC 가 발생함
– 특히 HazelCast 를 남용하면 , Full GC Time 문제가 발생 가능– 상용 버전의 HazelCast 의 경우 Direct Memory Access 를
이용하여 , 최소한의 GC Time 으로 사용이 가능함– 여러 인스턴스로 나눠서 메모리를 작게 잡고 , 부하를 분산 시켜 ,
Full GC 소요 시간과 , 발생 횟수를 줄여야 함
VS3. node.js 와 Vert.x 비교
Vert.x vs Node.JSVert.x Node.JS
에러처리 에러가 나더라도 STACK 을 출력하고 죽음 (추적이 용이 )
에러가 나면 , Context 정보 없이 죽음 (추적이 어려움 )
안정성 Netty,HazleCast 등 비교적 안정된 엔진위에 개발됨
V8 엔진 자체가 불안함
웹개발 없음 Express 등 웹 개발 프레임웍이 풍부함
프로그래밍 언어 Javascript,Python,Groovy,Java,Scala
Javascript
비동기 Non-Block-ing IO
쓰레드풀을 이용한 Emulation OS 수준의 Non-Blocking IO 사용 (IO 처리에 유리 )
지원 모듈 100 개 이하 40,000 개 이상
에코 시스템 공식 서적 2 개 (100 페이지 미만 )컨설팅 , 교육 업체 없음
레퍼런스 , 서적 , 교육 ,컨설팅등 매우 풍부
모니터링 없음 . 자바 모니터링 툴 사용 nodeTime(APM) 등 상용 모니터링 툴
클러스터링 HAHazleCast 와 HA 기능을 이용하여 제공
Redis 와 HaProxy 등으로 자체 구현 필요
결론• Start up 이나 , B2C 서비스는 node.JS 로 시작
– 자료 찾기 편리함– 자주 죽어서 문제가 될 때면 돈 벌었음 (컨설팅 받으세요 )
• 기술력이 충분하고 , 고성능 , 고안정 서비스가 필요할 경우 Vert.x 고려– 기반 엔진 자체가 튼튼하기 때문에 높은 성능과 안정성– 모듈들이 적고 , 자료가 부족하기 때문에 , 자체 기술력이 높아야함