node.js
JS Warm Up
- JavaScript platform like JVM of Java
- JSON
설치
- https://nodejs.org
- LTS (Long Term Support) 버전 또는 Current
nodeandnpm
node.js 개요
textNode.js® is a platform
built on Chrome's JavaScript runtime
for easily building fast, scalable network applications.
Node.js uses an event-driven, non-blocking I/O model
that makes it lightweight and efficient, perfect
for data-intensive real-time applications
that run across distributed devices.
특징
- JavaScript 기반 플랫폼
- Server-side
- Command Tool
- Desktop Application
장점
- 쉬운 시작
- 안정적인 서비스 w/ pm2
- 모듈 2,663,939 total packages(2024/01/27); https://modulecounts.com
- 성능 개선
- linkedin 사례
- 서버 감축 Ruby + Mongrel 30대 -> node.js 3대
- Frontend, Backend 개발자 소통 원활
- 잡다한 작업 감소해서 로직에 집중
- paypal 사례
- Java를 Node.js로 대치
- 더 적은 인원으로 개발 2배 정도 빨라짐
- 코드량 33%, 파일 40% 감소
- 성능 개선됨 (15-user: 11.3 vs 21.6 pages/sec)
- linkedin 사례
- C/C++ Addon
단점
- No Silver Bullet
- CPU과다 사용시 이슈
- 예외처리 실수하면 서버 다운 (pm2로 자동 재시작 가능)
- Callback Hell (Async로 커버 가능)
비동기 프로그래밍
- 자바스크립트의 경우 비동기 코드 패턴이 다반사
- 기존 코드와 달리 콜백 함수를 함께 넘겨주는 형태
- 이벤트 핸들링에 많이 쓰이는 기법
- 이벤트 루프 사용으로 싱글쓰레드 동작
blocking, non-blocking
- Input/Output
- IO latency
- L1: 3 cycles
- L2: 14 cycles
- RAM: 250 cycles
- DISK: 41,000,000 cycles
- NETWORK: 240,000,000 cycles
from: https://www.dropbox.com/s/o9g4m7tug3yt1xx/jsconf2009-nodejs.pdf?dl=0
- blocking code
textvar result = db.query("select * from T");
// use result
- non-blocking code
textdb.query("select * from T",
function(result) {
// use result
}
);
이벤트 루프
from blog.udemy.com/learn-node-js/
- 이벤트 루프 사용으로 싱글쓰레드 동작
- 기존 서버는 쓰레드 기반
- 아파치 등은 커넥션 증가에 따라서 메모리 증가
- nginx는 이벤트 루프 방식
서버사이드 자바스크립트 개발환경 설치
모듈 만들고 참조하기
- commonjs
const path = require('path')
ES6 setting
package.json"type": "module"import path from path
npm 을 통한 확장
- http://npmjs.org
- package.json
socket.io 모듈
json{
"name": "socket-chat-example",
"version": "0.0.1",
"description": "my first socket.io app",
"dependencies": {
"express": "^4.14.0",
"socket.io": "^4.1.2"
}
}
server.js
jsconst app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
socket.on('chat message', function (msg) {
io.emit('chat message', msg);
});
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
index.html
html<!doctype html>
<html lang="ko">
<head>
<title>Socket.IO chat</title>
<style>
- { margin: 0; padding: 0; box-sizing: border-box; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form id="form" action="">
<input id="input" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var messages = document.getElementById('messages');
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function (e) {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
socket.on('chat message', function (msg) {
var item = document.createElement('li');
item.textContent = msg;
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
</script>
</body>
</html>
실행
textnpm i
node server.js
expressjs 웹 프레임워크
- http://expressjs.com/
- npm install -g express-generator
- express myapp
- node.js의 기본 API인 http를 확장
- 기본 http
jsconst http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
express.js
- with package.json
npm init npm install express --save- create
exp.jsfile
jsvar express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
- 실행
node exp.js
express-generator
npm install express-generator -g- express.js의 scafold 코드 생성
express mywebcd myweb && npm install- run
npm start- or
node bin/www - or
DEBUG=myweb:* node bin/www
- or
basic routing
app.METHOD(PATH, HANDLER)- app is an instance of express.
- METHOD is an HTTP request method, in lowercase.
- PATH is a path on the server.
- HANDLER is the function executed when the route is matched.
get
jsapp.get('/', function (req, res) {
res.send('Hello World!')
})
curl 'localhost:3000'curl -XGET 'localhost:3000'
post
jsapp.post('/', function (req, res) {
res.send('Got a POST request')
})
curl -XPOST 'localhost:3000'
put
jsapp.put('/user', function (req, res) {
res.send('Got a PUT request at /user')
})
curl -XPUT 'localhost:3000/user'
delete
jsapp.delete('/user', function (req, res) {
res.send('Got a DELETE request at /user')
})
curl -XDELETE 'localhost:3000/user'
Routing
methods
get, post, put, head, delete, options, trace, copy, lock, mkcol, move, purge, propfind, proppatch, unlock, report, mkactivity, checkout, merge, m-search, notify, subscribe, unsubscribe, patch, search, connect.
- all
jsapp.all('/secret', function (req, res, next) {
console.log('Accessing the secret section ...')
next() // pass control to the next handler
})
Route Parameters
textRoute path: /users/:userId/books/:bookId
Request URL: http://localhost:3000/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }
textapp.get('/users/:userId/books/:bookId', function (req, res) {
res.send(req.params)
})
MairaDB 설치
MongoDB + node.js
node cluster 시작하기
- native cluster api
textconst cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
node.js clustering with PM2
JavaScript Code Quality
- SonarQube
- SonarLint
디버깅
개요
- debugging에서 알아야 할 용어들
- breakpoint : 중단점입니다. 실행 모드가 아닌 디버그 모드에서 프로그램을 중지하게 되는 지점의 표시입니다. 보통 ide에서 소스 라인 맨 앞 여백을 (더블)클릭하면 생깁니다. 다시 (더블)클릭하면 없어집니다. resume을 실행하면 다음 중단점을 만날 때까지 실행됩니다.
- step over : 한 줄을 실행합니다. 함수가 있어도 실행 후 다음으로 넘어갑니다.
- step into : 포커스된 라인에 있는 함수 내부로 들어갑니다.
- step out : 현재 함수를 끝까지 실행시키고, 호출시킨 곳으로 되돌아 갑니다.
- resume : 디버그로 한 줄 한 줄 실행시키는 트레이스 모드를 그만두고 다음 브레이크포인트를 만날 때까지 실행합니다.
node.js debug
textnode debug myscript.js
- myscript.js
textx = 5;
setTimeout(() => {
debugger;
console.log('world');
}, 1000);
console.log('hello');
- node-inspector (X)
- https://github.com/node-inspector/node-inspector#node-inspector
- 크롬브라우저를 독립적으로 띄워서 크롬 인스펙터 UI로 디버깅 가능
- http://okjsp.tistory.com/1165644244
npm install -g node-inspectornode-debug app.js
- node-emailer
- gmail smtp 설정 필요
- OAuth2
Test Frameworks
-
QUnit
-
Testing Essentials
-
UI 테스트
- GUITAR
- jmeter maven
- jenkins jmeter
서버 모니터링
text$ cd ~/dev/mongodb/bin
$ mkdir -p ~/data/db
$ ./mongod --dbpath=/Users/kenu/data/db
$ cd ~/dev/mongodb/bin
$ mongo
MongoDB shell version: 2.4.9
connecting to: test
> use uptime
switched to db uptime
> db.addUser('uptime', 'okpass');
{
"user" : "uptime",
"readOnly" : false,
"pwd" : "fdc9e10c8f90fac0c9fe786f28cc04f4",
"_id" : ObjectId("5577b97a62555c0332f63e6f")
}
> exit
$ git clone git://github.com/fzaninotto/uptime.git
$ cd uptime
$ npm install
-
PM2
- https://github.com/Unitech/PM2
pm2-dev: watch and restart
-
node server monitor
- alternative
- forever
- nodemon
- node-supervisor
- node-dev
영상
- 개요, 설치 https://www.youtube.com/watch?v=Z8cOppJwOeU
- socket.io, express.js https://www.youtube.com/watch?v=YWaoLdoqSWE
- express.js basic routing https://www.youtube.com/watch?v=KOtEZ0j0cic
- express.js api https://www.youtube.com/watch?v=-nHp0D4n4Do
- express.js resources https://www.youtube.com/watch?v=4bIIX07vN-8
- mariadb 연결(Windows) https://www.youtube.com/watch?v=VTBACySodEc
- node cluster https://www.youtube.com/watch?v=2v7oRhit8lQ
- node debugging https://www.youtube.com/watch?v=TaMYKdcBIGA
- Code Quality https://www.youtube.com/watch?v=1931C8MAvdM
- jade 2 ejs template https://www.youtube.com/watch?v=IeOoN1LZ4f0
- Express + MariaDB(mysql) Web App https://www.youtube.com/watch?v=UocHh8604Lc
- Async, Nested SQL https://www.youtube.com/watch?v=PJ7fQnDLmWg
related
ref
- node.js
- http://bit.ly/okjavascript
- http://bit.ly/oknodejs
- node.js 내가-쓰기로-선택한-이유
- octobersky.js
- PM2 (Process Monitor 2)
- node.js for other languages