Node.js의 도입과 활용
-
Upload
jin-wook-jeong -
Category
Technology
-
view
260 -
download
3
Transcript of Node.js의 도입과 활용
Node.JS의 도입과 활용
2015. 7. 22
Jinwook Jeong
NodeJS
Node.JS 소개
자바스크립트의 특성은 다른 동적 언어 매우 다르다 . 쓰레드에 대한 개념이 없다 .
동기화 모델은 이벤트를 기반으로 하여 완전하다 . Ryan Dahl
NodeJS
Node.JS 특징
• 이벤트 처리 I/O 프레임워크– Chrome V8 자바스크립트 엔진 위에서 동작– Single Thread 기반의 Event Loop 에 기반한 비동기 I/O
NodeJS
Node.JS 도입의 이유
• 서버가 응답상태를 클라이언트에 알려준다면 ?– 클라이언트가 서버에 쿼리를 날리지 않아도 비동기적 응답을 해줌– Non Blocking I/O 기반의 파일의 읽기 , 쓰기
• 자바스크립트로 서버프로그래밍을 할 수 있다면 ?– 프론트엔드 개발개발과 백엔드 개발을 단일언어 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; }
};}
Node.JS 를 위한 Javascript
NodeJS
• Hoisting– 마지막 선언을 끌어올리고 (Hoisting) 할당 부분을 그 자리에 둔다 .
– 호이스팅에 대한 시각적인 예
function f() {{
var x=1;var x=2;
}}
function f() {var x;{
x=1;x=2;
}}
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,
}
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;
Node.JS 도입을 위한 장단점
NodeJS
• 장점– 생산성
• Socket.IO 캡슐화 , JS 사용• CRUD rest api 구현이 용이함• Npm 에 기반한 외부모듈 도입 용이
– Redis, Mongodb, mysql 등
• 단점– Call Back Hell
• 이벤트 응답을 위해 함수가 중첩형태로 호출– 가독성 저해 요인 (asynchronous 모듈 이용이 가능하나 완전 해결책은 아님 )
– 유지보수의 어려움 • 특정 라인이 에러를 가지면 서버 자체가 다운됨• 신속한 장애대응 (Fast Troubleshooting) 이 어렵다 .
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
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 [ 모듈명 ]모듈삭제
Node.JS 활용 – 모듈로딩
NodeJS
• Module 로딩의 일반적인 예
var http=require(‘http’), util=require(‘util’), fs=require(‘fs’);
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');});
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/');
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
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 생략의 경우 모두에게 보내짐 }); });});
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>
..
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 프로젝트 생성
Node.JS 활용 – Express
NodeJS
• 탬플릿 엔진 비교
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');});
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){
}
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 서버 개발용이해짐
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');});
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);
});
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 })); }); });});
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 순으로 출력 )
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'); });}
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); });
Node.JS 활용 – 모듈화
NodeJS
• 자바스크립트에서 모듈패턴
var myspace= (function(){
myprivate=function(){return “this is myprivate”;
}return {
mypublicvar:”hello”,mypublic:function(){
return myprivate();
}}
})();
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’);
Node.JS 활용 – 모듈화
NodeJS
• Node.JS 에서의 메소드 체이닝을 이용한 모듈정의
module.exports=node;function node() {};
node.prototype.index=function() {}node.prototype.test=function(){}function test2(){ }
Node.JS 활용 – 모듈화
NodeJS
• 공개 API 작성예
• 비공개 API 작성예
module.exports={getMember:function(){},updateMember:function(){}
}
function updateLog (){console.log(‘update!’);setInterval( updateLog(),5000);
}
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); }});
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' …
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); });}
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
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');});
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
...