2015년 2월 20일 금요일

[nginx] nginx load balancer proxing

개요
nodejs는 싱글스레드 기반에서 운용되기 때문에, 멀티코어 환경에서 구동시 CPU를 100% 활용하지 않는다.

따라서, 1개 서버에서 코어수 만큼의 nodejs server를 기동한 환경을 전제로 했을때 nginx측에서 해당 서버의 각 nodejs server instance에 대해 load balancer proxy를 실시해주면 최대한의 자원을 이용할 수 있다.

참고자료
http://sailsjs.org/#!/documentation/concepts/Deployment/Scaling.html
# needs sticky session.

http://nginx.org/en/docs/http/load_balancing.html
#basics
#session presistance (sticky session)

수순

nodejs instance는 forever를 이용해 제각각 구동한다.
로컬의 파일시스템에서의 임시 파일들이 존재하므로, 소스들은 1개 instance단위로 분리해 배치토록 하자.

1. init script for forever nodejs app

우선 forever를 통한 sails.js app의 구동


forever start /<앱1의 경로>/app.js --port 5001 --prod
forever start /<앱2의 경로>/app.js --port 5002 --prod
forever start /<앱3의 경로>/app.js --port 5003 --prod
...

상기와 같은 코드를 /etc/init.d/{service_name}에 init script로서 배치한다.

#!/bin/bash
# chkconfig: 345 20 80
# description: portfolio sailsjs daemon
# processname: portfolio
### 상기 3줄을 통해 chkconfig에서 설정 가능케한다.
# ===============================
# init script
#
# @author nanhaprak
# @link http://nodeqa.com/nodejs_ref/25 # 참고한 설정
# ===============================
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin #forever나 node의 path문제 해결. 일반적인 path설정
APPHOME=/home/portfolio/ #예를들면 이번엔 이렇다.
case "$1" in
  start)
    forever start ${APPHOME}/app1/app.js --port 5001
    forever start ${APPHOME}/app2/app.js --port 5002
    ;;
  stop)
    forever stop ${APPHOME}/app1/app.js --port 5001
    forever stop ${APPHOME}/app2/app.js --port 5002
    ;;
  restart)
    forever restart ${APPHOME}/app1/app.js --port 5001
    forever restart ${APPHOME}/app2/app.js --port 5002
    ;;
  list)
    forever list
    ;;
  *)
    echo ###partial###C6F705E4-0637-40D0-B8A9-DF8D14EF4030quot;Usage: $0 {start|stop|list}"
    exit 1
esac

exit 0

2. nginx websocket load balancer configuration

1에서 nodejs자체의 구동을 완료했으므로, 이어서 nginx의 로컬서버내 로드밸런서 프록시를 작성토록 하자.

현재 작성중인 앱의 경우, socket.io, transport with websocket을 사용하고 있으므로, 프록시가 websocket에 대응될 필요가 있다.

우선 load balancer

/etc/nginx/nginx.conf

일부분만. 아래 upstream이 include되도록 하고, upstream목록은 따로 빼도록 하자.

...
http {
...
    include       /etc/nginx/upstreams;

이하, upstream 목록

/etc/nginx/upstreams

upstream sails_upstreams {
ip_hash; # sticky session support. (중요)
server 127.0.0.1:5001;
server 127.0.0.1:5002;
}

이하, virtual host 설정

/etc/nginx/conf.d/{appname}.conf

server {

    listen 80; # http인경우. https라면 443이 될것이다.
    server_name 호스트명;
    location / {

        # websocket proxy configuration
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;

        # general proxy configuration
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Queue-Start "t=${msec}000";

        # pass
        proxy_pass http://sails_upstreams;
    }
}

댓글 없음:

댓글 쓰기