Node.js의 도입과 활용

38
Node.JS 의 의의의 의의 2015. 7. 22 Jinwook Jeong

Transcript of Node.js의 도입과 활용

Page 1: Node.js의 도입과 활용

Node.JS의 도입과 활용

2015. 7. 22

Jinwook Jeong

Page 2: Node.js의 도입과 활용

NodeJS

Node.JS 소개

자바스크립트의 특성은 다른 동적 언어 매우 다르다 . 쓰레드에 대한 개념이 없다 .

동기화 모델은 이벤트를 기반으로 하여 완전하다 . Ryan Dahl

Page 3: Node.js의 도입과 활용

NodeJS

Node.JS 특징

• 이벤트 처리 I/O 프레임워크– Chrome V8 자바스크립트 엔진 위에서 동작– Single Thread 기반의 Event Loop 에 기반한 비동기 I/O

Page 4: Node.js의 도입과 활용

NodeJS

Node.JS 도입의 이유

• 서버가 응답상태를 클라이언트에 알려준다면 ?– 클라이언트가 서버에 쿼리를 날리지 않아도 비동기적 응답을 해줌– Non Blocking I/O 기반의 파일의 읽기 , 쓰기

• 자바스크립트로 서버프로그래밍을 할 수 있다면 ?– 프론트엔드 개발개발과 백엔드 개발을 단일언어 JS 로 처리할 수 있음

Page 5: Node.js의 도입과 활용

Node.JS 를 위한 Javascript

NodeJS

• Closure- 함수내부 변수들을 추적하고 조작하기 위한 함수

- 함수는 function scope 를 가지며 , 함수외부에서 함수내부 정의를 참조할 수 없으며 , JS 는 중첩된 함수를 허용함

– 클로저 생성을 위한 함수 표현식

function maker(){return function(){}

};

function maker(){var v=undefined;return {

set:function(p){v=p;},get:function(p){return p; },type:function(p){return typeof v; }

};}

Page 6: Node.js의 도입과 활용

Node.JS 를 위한 Javascript

NodeJS

• Hoisting– 마지막 선언을 끌어올리고 (Hoisting) 할당 부분을 그 자리에 둔다 .

– 호이스팅에 대한 시각적인 예

function f() {{

var x=1;var x=2;

}}

function f() {var x;{

x=1;x=2;

}}

Page 7: Node.js의 도입과 활용

Node.JS 를 위한 Javascript

NodeJS

• IIFE(immediately invoked function expression) 즉시실행함수– 지역변수의 Block Scope 지원을 위한 방법

– 즉시실행함수의 예

function f(){var v=0;console.log(v); //0for(var i=1,n=10;i<n;i++){

(function(){var v=i;console.log(v);//1-9return v;

})();}console.log(v); //0,

}

Page 8: Node.js의 도입과 활용

Node.JS 를 위한 Javascript

NodeJS

• Client J.S 와 Node.JS 의 차이점– Node 는 Google V8 을 이용하며 , ECMAScript 표준을 따름– Javascript 는 Browser version 에 의존적– Global 객체의 Priority

• Var localvar=myvalue; // Node.JS 는 지역변수가 global 변수보다 우선이다 .

– Node.JS 에서는 Global variable 을 global object 로 사용하며 , J.S에서는 Window variable 을 global object 로 사용함

• 브라우저 모드와 같이 처리– GLOBAL.window = GLOBAL;

Page 9: Node.js의 도입과 활용

Node.JS 도입을 위한 장단점

NodeJS

• 장점– 생산성

• Socket.IO 캡슐화 , JS 사용• CRUD rest api 구현이 용이함• Npm 에 기반한 외부모듈 도입 용이

– Redis, Mongodb, mysql 등

• 단점– Call Back Hell

• 이벤트 응답을 위해 함수가 중첩형태로 호출– 가독성 저해 요인 (asynchronous 모듈 이용이 가능하나 완전 해결책은 아님 )

– 유지보수의 어려움 • 특정 라인이 에러를 가지면 서버 자체가 다운됨• 신속한 장애대응 (Fast Troubleshooting) 이 어렵다 .

Page 10: Node.js의 도입과 활용

Node.JS 도입 – Node.JS 설치

NodeJS

yum -y groupinstall "Development Tools"wget http://nodejs.org/dist/v0.10.17/node-v0.10.17.tar.gz

tar zxf node-v0.10.17.tar.gzcd node-v0.10.17./configuremakemake install

Page 11: Node.js의 도입과 활용

Node.JS 도입 – NPM

NodeJS

• NPM 이란 ?• Node Package Modules 의 약자로 , Node.JS 모듈의 저장소

• NPM 의 사용이유• core module 인 http, file system, network, crypto 외에 필요한 모듈을

공급받음

• NPM 기본명령어 | $ npm install 패키지명설치

| $ npm ls [ 모듈명 ]설치된 모듈확인

| $ npm ls installed설치된 모든모듈확인

| $ npm uninstall [ 모듈명 ]모듈삭제

Page 12: Node.js의 도입과 활용

Node.JS 활용 – 모듈로딩

NodeJS

• Module 로딩의 일반적인 예

var http=require(‘http’), util=require(‘util’), fs=require(‘fs’);

Page 13: Node.js의 도입과 활용

Node.JS 활용 – 모듈로딩

NodeJS

• EJS 모듈로딩

// 모듈을 추출합니다 .var http = require('http');var fs = require('fs');var ejs = require('ejs');

// 서버를 생성하고 실행합니다 .http.createServer(function (request, response) {

fs.readFile('ejsPage.2.ejs', 'utf8', function (error, data) { response.writeHead(200, { 'Content-Type': 'text/html' }); response.end(ejs.render(data, { name: 'RintIanTta', description: 'Hello ejs With Node.js .. !' })); });}).listen(52273, function () { console.log('Server Running at http://127.0.0.1:52273');});

Page 14: Node.js의 도입과 활용

Node.JS 활용 – HTTP Server

NodeJS

• 웹 서버

var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n');}).listen(8000); console.log('Server running at http://localhost:8000/');

Page 15: Node.js의 도입과 활용

Node.JS 활용 – Socket.IO

NodeJS

var app = require('http').createServer(handler)var io = require('socket.io')(app);var fs = require('fs');

app.listen(80);

function handler (req, res) { fs.readFile(__dirname + '/index.html', function (err, data) { if (err) { res.writeHead(500); return res.end('Error loading in-dex.html'); }

res.writeHead(200); res.end(data); });}

io.on('connection', function (socket) { socket.emit('news', { hello: 'world' }); socket.on('my other event', function (data) { console.log(data); });});

| $ npm install sock-et.io

<script src="/socket.io/socket.io.js"></script><script> var socket = io('http://localhost'); socket.on('news', function (data) { console.log(data); socket.emit('my other event', { my: 'data' }); });</script>

Server (app.js) Client (index.html)

Using with HTTP Server

Page 16: Node.js의 도입과 활용

Node.JS 활용 – Socket.IO

NodeJS

// 모듈추출var fs = require('fs');

// 서버생성var server = require('http').createServer();var io = require('socket.io').listen(server);

// 서버실행server.listen(52273, function () { console.log('Server Running at http://127.0.0.1:52273');});

// 이벤트를 연결합니다 .server.on('request', function (request, response) { // 파일읽기 fs.readFile(‘test.html', function (error, data) { response.writeHead(200, { 'Content-Type': 'text/html' }); response.end(data); });});

// 소켓 서버 이벤트 연결io.sockets.on('connection', function (socket) { // client socket 에 대한 join 이벤트 socket.on('join', function (data) { socket.join(data); // 소켓을 어떤룸에 join 함 socket.set('room', data); });

// message 이벤트 socket.on('message', function (data) { socket.get('room', function (error, room) { io.sockets.in(room).emit('message', data); //or socket.broadcast.to(data).emit.. //to 생략의 경우 모두에게 보내짐 }); });});

Page 17: Node.js의 도입과 활용

Node.JS 활용 – Socket.IO

NodeJS

..<script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="/socket.io/socket.io.js"></script> <script> window.onload = function () { var room = prompt(' 방 이름을 입력하세요 .', ''); var socket = io.connect();

socket.emit('join', room); socket.on('message', function (data) { $('<p>' + data + '</p>').appendTo('body'); });

document.getElementById('button').onclick = function () { socket.emit('message', 'socket.io room message'); }; }; </script>

..

<button id="button">EMIT</button>

..

Page 18: Node.js의 도입과 활용

Node.JS 활용 – Express

NodeJS

• 특징– 라우팅– 세션 관리– 탬플릿 엔진 (ejs, jade..)– 기타 등등

• 설치

Express 설치 (4.0 기준 )

| $ npm install -g express

| $ npm install -g express-generator

탬플릿엔진 설치 | $ npm install express jade

| $ npm install express ejs

프로젝트 생성 | $ express simpleweb

create : simplewebcreate : simpleweb/package.jsoncreate : simpleweb/app.jscreate : simpleweb/publiccreate : simpleweb/public/javascriptscreate : simpleweb/public/imagescreate : simpleweb/routescreate : simpleweb/routes/index.jscreate : simpleweb/routes/users.jscreate : simpleweb/public/stylesheetscreate : simpleweb/public/stylesheets/style.csscreate : simpleweb/viewscreate : simpleweb/views/index.jadecreate : simpleweb/views/layout.jadecreate : simpleweb/views/error.jadecreate : simpleweb/bincreate : simpleweb/bin/wwwExpress 프로젝트 생성

Page 19: Node.js의 도입과 활용

Node.JS 활용 – Express

NodeJS

• 탬플릿 엔진 비교

Page 20: Node.js의 도입과 활용

Node.JS 활용 – Express

NodeJS

• 간단한 라우팅// 모듈을 추출합니다 .var http = require('http');var express = require('express');var app = express();

// 미들웨어를 설정합니다 .app.use(express.logger());app.use(app.router);app.use(express.static(__dirname + '/public'));

// 라우터를 설정합니다 .app.get('/a', function (request, response) { response.send('<a href="/b">Go to B</a>');});app.get('/b', function (request, response) { response.send('<a href="/a">Go to A</a>');});

// 서버를 실행합니다 .http.createServer(app).listen(52273, function () { console.log('Server running at http://127.0.0.1:52273');});

Page 21: Node.js의 도입과 활용

Node.JS 활용 – Express

NodeJS

• 라우팅시 정규식사용

• 라우팅 처리후 모듈별도 처리

app.get('/user/:id/:page[a-zA-Z]+’, function (request, response) { response.send(‘Hello');});

app.post('/login’,route.login);

exports.login=function(req,res){

}

Page 22: Node.js의 도입과 활용

Node.JS 활용 – RESTful Server

NodeJS

• RESTful Server

– 직관적인 URL 을 이용한 HTTP 기반의 SOAP 의 대체기술

– POST, GET, PUT, DELETE 라는 요청처리를 통해서 DB 의 기본동작인

CRUD(Create, Read, Update, Delete) 를 처리가 가능

– REST 는 비표준기술이면서 , 웹서비스에 대한 개방형 기술임

– 요청은 명령 (URL) 과 요청타입 (POST, GET) 과 요청컨텐츠 (POST 요청시 ) 에

대하여 여러 형태 (XML, JSON 등 ) 로 응답할 수 있도록 설계

– Express 모듈을 이용하면 RESTful 서버 개발용이해짐

Page 23: Node.js의 도입과 활용

Node.JS 활용 – RESTful Server

NodeJS

• Express 기반의 Restful Server

// 모듈추출var fs = require('fs');var http = require('http');var express = require('express');var app = express();

// 미들웨어 설정app.use(express.bodyParser());app.use(app.router);

// 라우터 설정app.get('/user', function (request, response) { });app.get('/user/:id', function (request, response) { });app.post('/user', function (request, response) { });app.put('/user/:id', function (request, response) { });app.del('/user/:id', function (request, response) { });

// 서버실행http.createServer(app).listen(52273, function () { console.log('Server running at http://127.0.0.1:52273');});

Page 24: Node.js의 도입과 활용

Node.JS 활용 – 비동기처리

NodeJS

• 비동기 로직

function getmember(user_id,callback){if(user_id){var data= ...//callback 함수 호출callback(data);}write_log();

}

getmember(‘user’,function(param){update(‘user’,param);

});

Page 25: Node.js의 도입과 활용

Node.JS 활용 – 비동기처리

NodeJS

• 비동기 로직 (callback hell...)

// 라우트를 수행합니다 .app.get('/', function (request, response) { // 파일을 읽습니다 . fs.readFile('list.html', 'utf8', function (error, data) { // 데이터베이스 쿼리를 실행합니다 . client.query('SELECT * FROM products', function (error, results) { // 응답합니다 . response.send(ejs.render(data, { data: results })); }); });});

Page 26: Node.js의 도입과 활용

Node.JS 활용 – 비동기처리

NodeJS

• 비동기 로직으로의 변환 (nextTick 활용 )– nextTick 으로 이벤트루프의 다음 차례까지로 연기함을 명시함

function Async(arg, cb){if(arg){

process.nextTick(cb);return;

}fs.stat(‘file’,cb);// 파일정보 표시//cb 대신 익명함수 function(){} 로 대체가능

}

function foo() { console.log('foo');} process.nextTick(foo);console.log('bar');//nextTick 에 의해 foo 는 이벤트 루프 처리가 완료된후 처리 (bar, foo 순으로 출력 )

Page 27: Node.js의 도입과 활용

Node.JS 활용 – 비동기처리

NodeJS

• 비동기 로직으로의 변환 (nextTick 활용 )

var client = net.connect(8124, function() { console.log('client connected'); client.write('world!\r\n'); // 동기적으로 실행되어 , client 가 초기화되기도 전에 콜백이 즉시 실행됨});

function asyncFake(data, callback) { if(data === 'foo') callback(true); else callback(false);} asyncFake('bar', function(result) { // 이 콜백은 실제로는 동기로 실행 });

// 항상 비동기가 되도록 정정function asyncReal(data, callback) { process.nextTick(function() { callback(data === 'foo'); });}

Page 28: Node.js의 도입과 활용

Node.JS 활용 – 비동기처리

NodeJS

• Async module(step) 을 이용한 비동기 로직처리

Step( function readSelf() { fs.readFile(__filename, this); }, function capitalize(err, text) { if (err) throw err; return text.toUpperCase(); }, function showIt(err, newText) { if (err) throw err; console.log(newText); });

Page 29: Node.js의 도입과 활용

Node.JS 활용 – 모듈화

NodeJS

• 자바스크립트에서 모듈패턴

var myspace= (function(){

myprivate=function(){return “this is myprivate”;

}return {

mypublicvar:”hello”,mypublic:function(){

return myprivate();

}}

})();

Page 30: Node.js의 도입과 활용

Node.JS 활용 – 모듈화

NodeJS

• 자바스크립트에서 메소드 체이닝을 이용한 모듈정의

var Dbcon=function(){this._host=‘’;this._port=0;

} Dbcon.prototype.host=function(host){

this._host=host;};Dbcon.prototype.port=function(port){

this._port=port;};Var conn=new Dbcon();conn.host(‘localhost’);conn.port(‘8080’);

Page 31: Node.js의 도입과 활용

Node.JS 활용 – 모듈화

NodeJS

• Node.JS 에서의 메소드 체이닝을 이용한 모듈정의

module.exports=node;function node() {};

node.prototype.index=function() {}node.prototype.test=function(){}function test2(){ }

Page 32: Node.js의 도입과 활용

Node.JS 활용 – 모듈화

NodeJS

• 공개 API 작성예

• 비공개 API 작성예

module.exports={getMember:function(){},updateMember:function(){}

}

function updateLog (){console.log(‘update!’);setInterval( updateLog(),5000);

}

Page 33: Node.js의 도입과 활용

Node.JS 활용 – MySQL

NodeJS

• MySQL

// 모듈을 추출합니다 .var mysql = require('mysql');

// 데이터베이스와 연결합니다 .var client = mysql.createConnection({ user: 'root', password: ' 비밀번호 ', database: 'Company'});

// 데이터베이스 쿼리를 사용합니다 .client.query('SELECT * FROM products', function (error, result, fields) { if (error) { console.log(' 쿼리 문장에 오류가 있습니다 .'); } else { console.log(result); }});

Page 34: Node.js의 도입과 활용

Node.JS 활용 – MySQL

NodeJS

• MySQL ActiveRecord Module– https://github.com/martintajur/node-mysql-activerecord

| $ npm install mysql-activerecord

var Db = require('mysql-activerecord');var db = new Db.Adapter({ server: 'localhost', username: 'root', password: '12345', database: 'test'});

db.select("id, CONCAT(first_name, ' ', last_name) as full_name, email");// This would produce: SELECT id, CONCAT(first_name, ' ', last_name) as full_name, email …

var conditions = { first_name: 'John', last_name: 'Smith'};db.where(conditions);// This would produce: … WHERE first_name = 'John' AND last_name = 'Smith' …

Page 35: Node.js의 도입과 활용

Node.JS 활용을 위한 Tip - Cluter

NodeJS

• Cluter 의 사용이유– 싱글코어에서 멀티코어 CPU 를 이용할때 ‘ Cluter’ 모듈을 이용함

var debug = require('debug')(‘ 구분이름 ');var app = require('./system/app');app.set('port', process.env.PORT || 3000);var cluster = require('cluster');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 { var server = app.listen(app.get('port'), function() { debug('Express server listening on port ' + server.address().port); });}

Page 36: Node.js의 도입과 활용

Node.JS 활용을 위한 Tip – Nodemon, Forever

NodeJS

| $ npm install -g nodemon

| $ npm install –g forever

운영시 서버를 백그라운드 형태로 실행가능

https://github.com/foreverjs/forever 사이트에 가면 해당 모듈 사용법이 나와 있음 그리고 아래와 같이 서버 실행 .

forever [action] [options] SCRIPT [script-options]

위 형태대로 주요 명령어를 살펴보면 다음과 같음 ‘ forever start server.js’

'forever list' 명령어 후에 인덱스 번호가 [0] 이 있다면

‘forever stop 0’ 과 같은 형태로 백그라운드에서 실행되는 노드를 종료할 수 있음

개발시 활용할 수 있는 서버 재실행 모듈

https://github.com/remy/nodemon

‘nodemon ./server.js localhost 8080’ 명령어를 이용하여 실행

Nodemon

Forever

Page 37: Node.js의 도입과 활용

Node.JS 활용을 위한 Tip – 쓸만한 프레임워크

NodeJS

• Sails– 라우팅을 MVC 형태로 구성이 가능함

• Koa.js– 차세대 Express 라고 불리우는 프레임워크– 콜백 함수 또는 콜백 지옥을 차단하고 미들웨어의 예외처리를 강화함

var koa = require('koa');var app = koa();

// x-response-time

app.use(function *(next){ var start = new Date; yield next; //yield 컨텍스트로 next 를 전달하고 , 요청응답은 next 에서 처리 var ms = new Date - start; this.set('X-Response-Time', ms + 'ms');});

Page 38: Node.js의 도입과 활용

Node.JS 활용을 위한 Tip – 기타 쓸만한 모듈

NodeJS

mocha : test framework (https://github.com/mochajs/mocha)| $ npm install -g mocha

Primus : real-time frameworks (https://github.com/primus/primus)| $ npm install -g nodemon

...