Node.js 쓰다보면 메모리를 점점 잡아먹는 현상을 발견할 있다. 이것은 굉장히 일반적인 현상이고, Node.js에서 쓰는 V8엔진은 기본으로 1.4GB 메모리를 한계로 잡아놓고(기본적으로 64비트는 1.4GB, 32비트는 512MB 한계로 잡는다.) 안에서 메모리를 점점 사용하게된다. 나의 경우는 아마존 프리티어를 사용하기때문에 메모리가 1GB 밖에 되지않아서 메모리 제한을 낮추어야했다.


--max-old-space-size=512

메모리 사용을 512MB 제한하라는 옵션이다. 아래와같이 사용할 있다.

혹은 forever 모듈을 사용하고있다면 아래와같이 사용하면 된다.


--expose-gc

가비지 컬랙터를 수동으로 전환한다. 내가 자바스크립트 코드에서 gc(); 호출하면된다. 적어도 30초에 한번씩은 가비지 컬랙팅을 하기를 추천 한다고 한다.


--max-new-space-size=2048

만약 서버 멈춤이 짧은것이 중요하다면 --max-new-space-size=2048 플래그를 사용하면 된다. 이것은 피크 퍼포먼스를 줄여버리기도하지만, 100ms정도로 서버 멈춤이 짧아질 것이다


--noincremental-marking

반면 피크 퍼포먼스가 중요하고 서버 멈춤이 오래 걸려도 괜찮다면 --noincremental-marking 플래그를 사용하면 된다. 플래그를 사용하면 1GB 1 정도의 서버 멈춤을 예상할 있다. 따라서 주로 작은 (heaps)이나 일괄 처리 테스크(순차 처리 테스크) 유용하게 사용된다.



참고

  • StackOverFlow : NodeJS / ExpressJS Memory Leak
    http://stackoverflow.com/questions/22507667/nodejs-expressjs-memory-leak
  • StackOverFlow : Is anybody making a Node-optimized V8?
    http://stackoverflow.com/questions/8263210/is-anybody-making-a-node-optimized-v8
  • 600k concurrent websocket connections on AWS using Node.js
    http://www.jayway.com/2015/04/13/600k-concurrent-websocket-connections-on-aws-using-node-js/
  • How does Node.js do memory allocation?
    https://www.quora.com/How-does-Node-js-do-memory-allocation



WRITTEN BY
tucan.dev
개인 iOS 개발, tucan9389

,

원문 : https://blog.risingstack.com/fundamental-node-js-design-patterns/

Translated by canapio
Help by soojin

디자인패턴에 대해 이야기할 때 당신은 singleton, observer, factory들을 생각할 것이다. 이 글은 단지 그것들에 대해서만 이야기하는것은 아니고 dependency injection이나 middleware와 같은 다른 일반적인 패턴과 함께 다룰것이다.

디자인 패턴이란?

디자인 패턴은 흔히 발생하는 문제를 재사용가능하게 일반화하여 해결한다.

Singleton

singleton 패턴들은 해당 "클래스"의 인스턴스 갯수를 한개로 한정한다. Node.js에서는 require을 사용함으로써 꽤 쉽게 싱글톤을 만들 수 있다.

//area.js
var PI = Math.PI;

function circle (radius) { 
  return radius * radius * PI;
}

module.exports.circle = circle; 

당신의 응용프로그램에서 싱글턴 객체를 얼마나 사용하든 상관없이; 오직 하나의 객체로 존재하게 될 것이다.

var areaCalc = require('./area');

console.log(areaCalc.circle(5));

require의 동작 덕분에, 싱글톤들은 NPM모듈들 사이에서 가장 일반적인 Node.ja 디자인 패턴들일 것이다

Observer

한 객체는 상태가 바뀔때 dependents나 observer의 리스트를 자동으로 유지하고 그것들을 알린다. Observer 패턴을 구현하기 위해서는 EventEmitter를 끌어 사용해야한다.

// MyFancyObservable.js
var util = require('util');  
var EventEmitter = require('events').EventEmitter;

function MyFancyObservable() {  
  EventEmitter.call(this);
}

util.inherits(MyFancyObservable, EventEmitter);  

이것이 그 방법이다; 우리는 단지 옵저버가 가능한 객체를 만들었다! 이것을 유용하게 만들기 위해서는 몇가지 기능을 추가하면 된다.

MyFancyObservable.prototype.hello = function (name) { 
  this.emit('hello', name);
};

잘 했다. 이제 우리의 observable은 이벤트를 발생시킬 수 있다. 이제 사용해보자!

MyFancyObservable.prototype.hello = function (name) { 
  this.emit('hello', name);
};

Factory

팩토리 패턴은 생성자 대신 제네릭한 인터페이스를 만들어야 하는 creational pattern이다.
이 패턴은 만들려는 프로세스가 복잡할 때 굉장히 유용하게 쓰인다.

function MyClass (options) {  
  this.options = options;
}

function create(options) {  
  // modify the options here if you want
  return new MyClass(options);
}

module.exports.create = create;  

펙토리는 테스팅 또한 쉽게 만든다. 가령 이 패턴을 이용해 모듈에 dependency를 넣을 수 있다.

Dependency Injection

Dependency injection은 의존객체에 하나 이상의 dependency를 주입하거나 참조로 전달하는 소프트웨어 디지인 패턴이다.     

예를들어 데이터베이스에 의존적인 UserModel을 생성해보자.

function userModel (options) { 
  var db;

  if (!options.db) {
    throw new Error('Options.db is required');
  }

  db = options.db;

  return {
    create: function (done) {
      db.query('INSERT ...', done);
    }
  }
}

module.exports = userModel;

이제 이걸 이용해서 인스턴스를 만들 수 있다.

var db = require('./db');

var userModel = require('User')({  
  db: db
});

왜 이게 유용한가? 이것은 테스팅을 엄청나게 쉽게 만들어준다 -당신이 유닛테스트를 만들 때, 이 모델에 가짜 db 인스턴스를 쉽게 넣어줄 수 있다.

Middleware / pipeline

Middleware는 강력하지만 아주 심플한 컨셉이다: 한 유닛이나 한 함수의 결과값은 다음을 위한 인풋이다. 만약 당신이 이미 ExpressKoa를 사용했다면 이 컨셉을 이미 사용해보았다.

Koa가 어떻게 그것을 하는지 확인해보자:

app.use = function(fn){  
  this.middleware.push(fn);
  return this;
};

기본적으로 이 코드는 middleware를 추가하면 단순히 middleware 배열에 추가한다. 지금까지는 잘 되고 있다. 그러나 서버에 요청을 하면 어떨까?

var i = middleware.length; 
while (i--) { 
  next = middleware[i].call(this, next);
}

마법이 아니다 - 당신의 middleware는 줄줄이 호출된다. 

Streams

stream은 특별한 pipeline으로 생각할 수 있다. 이것은 객체가 아닌 bytes이지만 많은 양의 데이터 흐름을 처리하는 데 좋다.

process.stdin.on('readable', function () {  
    var buf = process.stdin.read(3);
    console.dir(buf);
    process.stdin.read(0);
});

$ (echo abc; sleep 1; echo def; sleep 1; echo ghi) | node consume2.js 
<Buffer 61 62 63>  
<Buffer 0a 64 65>  
<Buffer 66 0a 67>  
<Buffer 68 69 0a>  

Example by substack

stream에 대해 더 공부하고 싶으면 substack의 Stream Handbook을 확인해보자.

Further reading



WRITTEN BY
tucan.dev
개인 iOS 개발, tucan9389

,
OS : centos 32bit
mongodb : 3.0.2


1. 아래 링크에 들어가서 해당 OS의 MongoDB 다운로드 URL 준비한다.

2. 리눅스에 curl 명령을 실행하여 MongoDB 압축파일을 다운받는다.
# curl -O [1번에서가져온URL]
예) # curl -O https://fastdl.mongodb.org/linux/mongodb-linux-i686-3.0.2.tgz

3. 압축을 푼다 (# ls를 해보면 해당 디렉토리에 들어있는 파일을 볼 수 있다)
# tar -zxvf 압축파일이름
예) # tar -zxvf mongodb-linux-i686-3.0.2.tgz

4. 압축을 푼 폴더를 /opt/nosql 으로 옮긴다.
# mkdir /opt/nosql
# mv mongodb-linux-i686-3.0.2 /opt/nosql/mongodb

5. db가 저장될 폴더를 만든다.
# mkdir -p /data/db

6. mongodb 디렉터리로 들어가서 mongod를 실행시킨다.
# cd /opt/nosql/mongodb

(7. mongodb 클라이언트를 실행시켜본다.)
# export PATH=/opt/nosql/mongodb/bin:$PATH  // monodb 클라이언트를 바로 실행할 수 있게 해줌
# mongdb
>


빠르게 훑어보는 nodejs, mongodb 연동 : http://bcho.tistory.com/889


참고 



WRITTEN BY
tucan.dev
개인 iOS 개발, tucan9389

,