소규모 모임, 회사 프로젝트 등 여러명이 일을 할 때가 많다. 

2명이서 일 할 경우에는 메일, 문자, 카톡 등 커뮤니케이션 채널이 단순 하지만 3명 이상이 될 경우에는 혼선이 올 수 있다.


규모가 좀 있거나 대형 프로젝트를 할 때는 레드마인을 주로 사용 하는 것 같다.


Redmine

▷ 공식 사이트: http://www.redmine.org/


오픈 소스로 구성이 되어 있으며, 프로젝트를 전체적으로 관리하는 차원에서 관리가 수월 하다. 

개발자들 편의 제공을 위해 git과도 연동이 가능 하다.



Trello

▷ 공식 사이트: https://trello.com/login


회사에서 일을 하다보면 초록색 빛나는 칠판에 압정으로 포스트잇을 꼽아 놓은 모습을 볼 수 있을 것이다. 

그와 비슷한 UI로 구성되어 있다. 매니저 느낌이 난다. ㅋ


Google 계정과 연동이 가능하고 Android, iOS 앱도 있다. 실시간 이기 때문에 커뮤니케이션 채널로 활용 하기에는 최적이라고 생각이 된다. 


메뉴 구성도 간단하게 되어 있다.


To Do - Doing - Done

할일 - 하는중 - 끝



위와 같은 가상의 매니저를 이용해서 좋은 프로젝트가 됬으면 하는 바램이다.

개발자들 화이팅 ~ !!!



Express 공식 사이트의 설명 이다.


위 방법대로 사용 할 경우 많은 편의성이 제공 된다.

명시 되지 않은 두번째 인자가 있다.


req.param(name, defaultValue)

defaultValue: 값이 undefined 인 경우 기본 값을 설정 한다.


Ex) req.param('name', 'sample')

위와 같이 사용 한다.


※ 참고 사이트

  - nodejs/express: http://expressjs.com/api.html#req.param



nodejs logging 라이브러리에서 winston이 활발하게 사용 되고 있다. 사용 하다보면 시간이 안맞는 경우가 발생 하기도 한다.


ntp 타임서버 설정을 해서 linux 상에서 time 확인을 해보았다.

2013. 09. 23. (월) 12:02:11 KST

정상적으로 나온다. 하지만 log 에서는 -9시간 전으로 나온다.

2013-09-23T03:02:11.913Z ...

해결 방법

../winston/lib/winston/common.js 파일을 수정 한다.

//
// ### function timestamp ()
// Returns a timestamp string for the current time.
//

exports.timestamp = function () {
  // 수정
};

위 function 을 재 구현하면 시간이 원하는 포맷으로 출력 된다.


※ 참고 사이트

  - nodejs/winston: https://github.com/flatiron/winston


'Nodejs' 카테고리의 다른 글

Nodejs Memory 관리  (0) 2013.11.11
Express req.param 사용 하기  (0) 2013.09.23
Nodejs cluster process 값 공유 하기  (0) 2013.08.29
Nodejs Express logger format 설정 하기  (0) 2013.08.01
Nodejs pg library connection pool 관련  (0) 2013.05.16


공통 적으로 쓰이는 시스템 로그 가끔 확인 할 때가 필요 하다.


위치: /var/log/messages


Sep  6 11:27:52 localhost ntpd[5514]: ntpd 4.2.4p8@1.1612-o Fri Feb 22 11:23:27 UTC 2013 (1)

Sep  6 11:27:52 localhost ntpd[5515]: precision = 0.108 usec

Sep  6 11:27:52 localhost ntpd[5515]: Listening on interface #0 wildcard, 0.0.0.0#123 Disabled

Sep  6 11:27:52 localhost ntpd[5515]: Listening on interface #1 wildcard, ::#123 Disabled

Sep  6 11:27:52 localhost ntpd[5515]: Listening on interface #2 eth0, fe80::ea40:f2ff:feef:20d3#123 Enabled

Sep  6 11:27:52 localhost ntpd[5515]: Listening on interface #3 lo, ::1#123 Enabled

Sep  6 11:27:52 localhost ntpd[5515]: Listening on interface #4 lo, 127.0.0.1#123 Enabled

Sep  6 11:27:52 localhost ntpd[5515]: Listening on interface #5 eth0, 192.168.0.xx#123 Enabled

Sep  6 11:27:52 localhost ntpd[5515]: Listening on routing socket on fd #22 for interface updates

// ... ing


꾸준히 쌓이고 있다.. 날짜 별로 백업도 되는 거 같다.



 Server와 Client를 연동 할 경우 시간 오차가 발생 할 수 있다. 강제로 시간을 맞추어 보려고 하였으나, ntp 설정을 할 경우 해결이 가능 하다.


ntp 가 설치가 되어 있지 않는 경우 아래 명령어를 실행 하여 설치 하자.


[whitelife@localhost ~]$ yum install ntp


설정 하기

파일: /etc/ntp.conf

# For more information about this file, see the man pages
# ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5).

driftfile /var/lib/ntp/drift

# Permit time synchronization with our time source, but do not
# permit the source to query or modify the service on this system.
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery

# Permit all access over the loopback interface.  This could
# be tightened as well, but to do so would effect some of
# the administrative functions.
restrict 127.0.0.1
restrict -6 ::1

# Hosts on local network are less restricted.
restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#server 0.centos.pool.ntp.org
#server 1.centos.pool.ntp.org
#server 2.centos.pool.ntp.org

server kr.pool.ntp.org
server time.bora.net
server time.nuri.net

#broadcast 192.168.1.255 autokey        # broadcast server
#broadcastclient                        # broadcast client
#broadcast 224.0.1.1 autokey            # multicast server
#multicastclient 224.0.1.1              # multicast client
#manycastserver 239.255.254.254         # manycast server
#manycastclient 239.255.254.254 autokey # manycast client

# Undisciplined Local Clock. This is a fake driver intended for backup
# and when no outside source of synchronized time is available. 
#server 127.127.1.0     # local clock
#fudge  127.127.1.0 stratum 10  

# Enable public key cryptography.
#crypto

includefile /etc/ntp/crypto/pw

# Key file containing the keys and key identifiers used when operating
# with symmetric key cryptography. 
keys /etc/ntp/keys

# Specify the key identifiers which are trusted.
#trustedkey 4 8 42

# Specify the key identifier to use with the ntpdc utility.
#requestkey 8

# Specify the key identifier to use with the ntpq utility.
#controlkey 8

# Enable writing of statistics records.
#statistics clockstats cryptostats loopstats peerstats
위와 같이 설정 파일을 수정 한다.
사설 IP 에 따라서 local network 설정을 192.168.x.x 로 설정 한다.

동기화 하기


[whitelife@localhost ~]$ sudo ntpdate -b time.bora.net

22 Dec 05:47:19 ntpdate[19906]: step time server 203.248.240.140 offset -0.030816 sec



SyntaxHighlighter 는 오픈 소스 이며 클라이언트 자바 스크립트로 구성 되어 있다.


공식 사이트: http://alexgorbatchev.com/SyntaxHighlighter/

참고 사이트: http://mindgear.tistory.com/164


정리가 잘 되어 있어 쉽게 따라 할 수 있었다.


Syntax 구성 표


 Syntax

 file

 applescript

 shBrushAppleScript.js 

 actionscript3 as3

 shBrushAS3.js 

 bash shell 

 shBrushBash.js 

 coldfusion cf

 shBruchColdFusion.js

 cpp c

 shBruchCpp.js

 c# c-sharp csharp

 shBruchCSharp.js

 css shBruchCss.js
 delphi pascal shBruchDelphi.js
 diff patch pas shBruchDiff.js

 erl erlang

 shBruchErlang.js

 groovy

 shBruchGroovy.js

 java

 shBruchJava.js

 jfx javafx

 shBruchJavaFX.js

 js jscript javascript shBruchJScript.js
 perl pl

 shBruchPerl.js

 php shBruchPhp.js
 text plain shBruchPlain.js
 py python shBruchPython.js

 ruby rails ror rb

 shBruchRuby.js
 sass scss

 shBruchSass.js

 scala

 shBruchScala.js

 sql

 shBruchSql.js
 vb vbnet shBruchVb.js
 xml xhtml xslt html shBruchXml.js


적용 방법 


Step 1.  글 작성 시 HTML 모드로 변경

아래 내용 추가 하기 


<pre class="brush: text">


  // ...


</pre>


Step 2.  화면 확인 하기

// ... test
// ... test
// ... test

위와 같이 확인이 가능 하다.


발생 시점

Redis 시작 스크립트 사용 시


[whitelife@localhost init.d]$ sudo service redis stop

/var/run/redis_6379.pid does not exist, process is not running


위와 같이 redis 가 사용 중 인데 pid 를 찾지 못하여 스크립트가 process를 못 찾는 경우가 발생 한다.


해결 방법

설정 파일을 수정 아래와 같은 부분을 확인 하자.


설정 파일: redis.conf

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes

# When running daemonized, Redis writes a pid file in /var/run/redis.pid by
# default. You can specify a custom pid file location here.
pidfile /var/run/redis_6379.pid

# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379

스크립트 파일: redis

#!/bin/sh
#
# chkconfig: 2345 64 36
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.

REDISPORT=6379
EXEC=/usr/bin/redis-server
CLIEXEC=/usr/bin/redis-cli

PIDFILE=/var/run/redis.pid
CONF="/etc/redis/redis.conf"

case "$1" in
    start)
        if [ -f $PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed"
        else
                echo "Starting Redis server..."
                $EXEC $CONF
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running"
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
                $CLIEXEC -p $REDISPORT shutdown
                while [ -x /proc/${PID} ]
                do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped"
        fi
        ;;
    *)
        echo "Please use start or stop as first argument"
        ;;
esac

1.  daemon 사용시 daemonize 옵션을 활성화 해야 한다.

2.  pidfile 경로를 확인 한다.


서비스 시작 하기

[whitelife@localhost init.d]$ sudo service redis start

Starting Redis server...

[whitelife@localhost init.d]$ sudo service redis stop

Stopping ...

Redis stopped


pid 파일 확인 하기

서비스가 시작 된 후 해당 경로에서 확인 하자.

[whitelife@localhost run]$ ll | grep redis

-rw-r--r--. 1 root      root         6 2013-09-05 12:03 redis.pid

[whitelife@localhost run]$ 






Sample Code.

Express와 같이 사용 하였다.

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');

var app = express();

var cluster = require('cluster')
  , numCPUs = require('os').cpus().length;

function setting() {
  app.configure(function(){
    app.set('port', process.env.PORT || 3000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser('your secret here'));
    app.use(express.session());
    app.use(app.router);
    app.use(express.static(path.join(__dirname, 'public')));
  });

  app.configure('development', function(){
    app.use(express.errorHandler());
  });

  app.get('/', routes.index);
  app.get('/users', user.list);

  http.createServer(app).listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
  });
}

function eachWorker(callback) {
  for (var id in cluster.workers) {
    callback(cluster.workers[id]);
  }
}

// master
if (cluster.isMaster) {
  for (var i=0; i<numCPUs; i++) {
    var worker = cluster.fork();

    worker.on('message', function(message) {
      if (message.cmd == 'broadcast') {
        console.log('send worker');

        setInterval(function() {
          eachWorker(function(_worker) {
            _worker.send({ cmd: 'broadcast', message: 'test message' });
          })
        }, 1000);
      }
    });
  }

  cluster.on('exit', function(worker, code, signal) {
    log.info('worker ' + worker.process.pid + ' died');
  });

// worker
} else {
  if (cluster.isWorker) {
    console.log(' I am worker ' + cluster.worker.id);

    process.on('message', function(message) {
      if (message.cmd == 'broadcast') {
        console.log('receive message: ' + message.message);
      }
    });

    process.send({ cmd: 'broadcast' });
  }
}

1.1  Master (Parent)

부모 프로세스 로 볼 수 있으며 자식 프로세스를 생성 한다. 위 코드를 참고 시 'broadcast' 라는 명령어로 event 감지 하여 데이터를 주고 받는다.


1.2  Worker (Child)

부모 프로세스 가 fork() 할 경우 생성 된다. 해당 프로세스는 생성 되는 시점에서 'message' 라고 명령어를 보낸다.


1.3  Test 

sample를 실행해 보자.


whitelife@whitelife:~/work/cluster_test$ node app.js 

 I am worker #1

send worker.....

 I am worker #2

send worker.....

receive message: test message

receive message: test message


※ 참고 사이트

  - node api: http://www.nodejs.org/api/cluster.html


+ Recent posts