Post on 29-Nov-2014
description
https://www.facebook.com/JohnKim0331!http://stalk.io
영어영문학을 전공하고, 인문학에 관심이 많고, 피아노가 특기며, 코딩이 취미인 자랑스러운 대한민국 개발자입니다.
LG CNS 에서 SI 프로젝트의 분석/설계/개발 그리고 아키텍트 등 다양한 경험을 하고 있으며, 요즘은 다양한 오픈소스를 활용한 분산 아키텍처 설계/검증에 전념하고 있습니다. !엔지니어는 누구보다 객관적이어야 하기에 항상 겸손하고 끊임없이 탐구하려고 노력 중입니다.
- DEVIEW, JCO 등 컨퍼런스 발표, NIPA 오픈프론티어!- Server Side Architecture Group 회원 ^^;
김요한 (John Kim)
PayPal is concentrating on training for their developers to help understand !
functional and asynchronous coding.
2014, eBay !will be using node for the front end, !
and Scala / Java for the services.Scala / Java for the services
The harder transition was not from Ruby and Java to node, !it was from OO to functional programming.
PayPal wrote the same app twice in Node and Java.
Node was 2x requests/sec, !33% less code, !
35% less response time.
https://www.paypal-engineering.com/2013/11/22/node-js-at-paypal/
https://www.paypal-engineering.com/2013/11/22/node-js-at-paypal/
처음에는 상대적으로 성능이 저하 될 수 있다.
request 가 많을 수록 효과 적이다.
The 250-500 ms node process start / stop time has been a huge benefit at LinkedIn and Groupon.Fast deployment is a huge advantage for node. !Hard to deploy multiple times a day when it takes 2 hours each time.
Small, reusable modules, unix philosophy, and not investing too much in frameworks.
Unix Philosophyhttp://en.wikipedia.org/wiki/Unix_philosophy
var io = require('socket.io').listen(80); !var chat = io.of('/chat') .on('connection', function (socket) { socket.emit('a message', { that: 'only' , '/chat': 'will get' }); chat.emit('a message', { everyone: 'in' , '/chat': 'will get' }); }); !var news = io.of('/news') .on('connection', function (socket) { socket.emit('item', { news: 'item' }); });
server.js<script> var chat = io.connect('http://localhost/chat') , news = io.connect('http://localhost/news'); chat.on('connect', function () { chat.emit('hi!'); }); news.on('news', function () { news.emit('woot'); }); </script>
client.js
var io = require('socket.io').listen(80); !var chat = io.of('/chat') .authorization(function (handshakeData, callback) { if(isValid(handshakeData.query.token){ callback(null, true); }else{ callback('Token is not valid.', false); }; }) .on('connection', function (socket) { console.log(socket.handshake.token); }); ! . . . . .
<script> var chat = io.connect(‘http://localhost/chat?token=GAV3RWDG67WA’) . . . . . </script>
server.js
client.js
!io.enable('browser client minification’); io.enable('browser client etag'); !io.enable('browser client gzip'); !!io.set('log level', 1); !io.set('transports', [ 'websocket' , 'flashsocket' , 'htmlfile' , 'xhr-‐polling' , 'jsonp-‐polling' ]);
server.js
flashsocket 사용하기!포트번호 10843 열어야 함.
gzip 압축
0 - error / 1 - warn / 2 - info / 3 - debug
브라우져 캐쉬를 위한 ETag 설정
javascript 파일 minified
var socket = io.connect('http://XXXXXXXXXXX', { 'resource: ‘socket.io', 'connect timeout: 10000, 'try multiple transports: true, 'reconnect: true, 'reconnection delay: 500, 'reconnection attempts': 10, 'sync disconnect on unload': false, 'auto connect': true, 'flash policy port': 10843, 'force new connection': false });
client.js
unload 이벤트 발생시 disconnect 이벤트 전송!(xhr-polling 인 경우에 유용함)
동일한 페이지에서 여러개의 socket connection 을 연결해야 하는 경우 필요함
!module.exports = function(grunt) { concat: { dist: { src: [ 'src/client.js', 'node_modules/socket.io-‐client/dist/socket.io.js', 'src/json2.js'], dest: 'public/client.js' }, }, uglify: { dist: { src: '<%= concat.dist.dest %>', dest: ‘public/client_min.js' }, } };
Gruntfile.js
> grunt
https://github.com/xpush/stalk.io/blob/master/Gruntfile.js
!#!/usr/bin/env node !var io = require('socket.io').listen(80); !var chat = io.of(‘/chat') .authorization(function (handshakeData, callback) { if(isValid(handshakeData.query.token){ callback(null, true); }else{ callback('Token is not valid.', false); }; }) .on('connection', function (socket) { console.log(socket.handshake.token); }); ! . . . . .
server
> server
https://github.com/xpush/node-xpush/blob/master/bin/xpush
. . . . . . .
. . . . . . .
Apache ZooKeeper™+/servers/10.54.22.102:8088 /10.54.22.103:8100 /10.54.22.103:8110
10.54.22.102:8088
10.54.22.103:8100
10.54.22.103:8110
10.54.22.104:8120 /10.54.22.104:8120
var zookeeper = require(‘node-‐zookeeper-‐client’); var zkClient = zookeeper.createClient(address, { retries : 2 }); !zkClient.create( ‘/servers/10.54.22.102:8088’, zookeeper.CreateMode.PERSISTENT, function (error) { . . . .} );
Apache ZooKeeper™
var zookeeper = require(‘node-‐zookeeper-‐client’); var zkClient = zookeeper.createClient(address, { retries : 2 }); !zkClient.create( ‘/servers/10.54.22.102:8088’, zookeeper.CreateMode.PERSISTENT, function (error) { . . . .} );
네트워크의 일시적 장애로 !서버가 죽은것으로 오판하면 안된다.
zookeeper.CreateMode.PERSISTENTzookeeper.CreateMode.EPHEMERAL
Apache ZooKeeper™
인스턴스 할당서버 10.54.22.102:80
10.54.22.102:8088
10.54.22.103:8100
10.54.22.103:8110
10.54.22.104:8120
Apache ZooKeeper™/servers/10.54.22.102:8088 /10.54.22.103:8100 /10.54.22.103:8110 /10.54.22.104:8120
채팅방(이름:SSAG) 접속할꺼임!
10.54.
22.103
:8110
Socket 연결
채팅방(이름:SSAG)
채팅방 SSAG 에 어느 서버를 할당해 줄까?
인스턴스 할당서버 10.54.22.102:80
10.54.22.102:8088
10.54.22.103:8100
10.54.22.103:8110
10.54.22.104:8120
Apache ZooKeeper™/servers/10.54.22.102:8088 /10.54.22.103:8100 /10.54.22.103:8110 /10.54.22.104:8120
채팅방(이름:SSAG) 접속할꺼임!
10.54.
22.103
:8110
Socket 연결
채팅방(이름:SSAG)
Consistent Hashing채팅방 SSAG 에 어느 서버를 할당해 줄까?
인스턴스 할당서버 10.54.22.102:80
10.54.22.102:8088
10.54.22.103:8100
10.54.22.103:8110
10.54.22.104:8120
Apache ZooKeeper™/servers/10.54.22.102:8088 /10.54.22.103:8 /10.54.22.103:8 /10.54.22.104:8
채팅방접속할꺼임 채팅방
10.54.
22.103
:8
Socket
채팅방
<Set/Get>
SSAG -‐ Server3^2 MS -‐ Server2^1 LGCNS-‐ Server1^4
체팅방명
접속된서버^접속자수connect : +1 disconnect : -‐1 (0 이면 DEL)
https://github.com/sockjs/sockjs-node
WebSockets
Socket.IO
Engine.IO
BrowserChannel
SockJS
https://github.com/einaros/ws
https://github.com/LearnBoost/engine.io
https://github.com/LearnBoost/socket.io
https://github.com/josephg/node-browserchannel
https://github.com/sockjs/sockjs-node
WebSockets
Socket.IO
Engine.IO
BrowserChannel
SockJS
https://github.com/einaros/ws
https://github.com/LearnBoost/engine.io
https://github.com/LearnBoost/socket.io
https://github.com/josephg/node-browserchannel
an abstraction layer for real-time to prevent module lock-in
primushttp://primus.io
https://github.com/bwcho75/node.js_study/tree/master/node_chatting_101_primus
https://github.com/bwcho75/node.js_study/tree/master/node_chatting_101
primus 를 활용하여 모듈 종속성 제거하기 예제 socket.io -> primus (sockJS)
xpush session server
xpush channel server
xpush channel server
xpush channel server. . . . .
Apache ZooKeeper™
https://github.com/xpush/stalk.iohttps://github.com/xpush/node-xpush
Currently under development.
xpush session server
xpush channel server
xpush channel server
xpush channel server. . . . .
Apache ZooKeeper™
A 메신져
B 모바일 앱실시간 Push Notification
C 홈쇼핑 웹기반 온라인 채팅 상담 서비스
D 상황판 실시간 Dashboard
- xpush session server : client 에 접속할 체널서버 분배 할당 / 사용자 인증!- xpush channel server : 실제로 메시징을 주고 받는 socket 서버 / Push Notification 처리!- zookeeper : 분산 체널 서버 관리 - redis : 실시간 체널 서버 사용 정보 동기화 및 서버간 메시지 공유 - mongoDB : 송수진 메시지 저장 관리
회사의 다른 기간 시스템