วันอังคาร, ตุลาคม 14, 2551
ติดตั้ง Rails Mongrel Cluster บน Ubuntu Hardy (8.04)
ทดลองมาหลาย solution สุดท้ายมาได้เป็น solution ง่ายๆ แบบนี้ครับ

การ Deploy เราค่อยๆ ทำตามลำดับดังนี้
1. ติดตั้ง Application ของเราบน mongrel ให้ขึ้นได้ก่อน
============================
**Adduser**
สร้าง user สำหรับ run mongrel เวลากำหนดสิทธิ์จะได้ง่ายหน่อย
สำหรับ Ubuntu
sudo /usr/sbin/adduser mongrel
สำหรับ Redhat, "-r" คือไม่ต้องสร้าง home ไม่ต้องมี attribute มากมายให้ user
sudo /usr/sbin/adduser -r mongrel
**Deploy application**
ติดตั้ง application ของเราไว้ที่ /var/www/
sudo mkdir /var/www
sudo mkdir /var/www/application_name
sudo chown -R mongrel:mongrel /var/www/application_name
เอา application ของเรามาใส่ไว้ในที่ๆ เตรียมไว้ จะเอาออกมาจาก svn หรือ copy มาใส่ก็ได้ ไว้ตอนต่อไปเราค่อยมา set capistano กัน
svn export svn://svn_server.com/application_name/trunk/ --username name --password pass .
rake db:create:all
rake db:migrate RAILS_ENV="production"
ทดลอง run ดูก่อนว่าทำงานได้หรือเปล่า
./script/server -e production
**Setup Mongrel Cluster**
เมื่อหนึ่งตัวทำงานได้ ต่อไปก็ทำให้เป็น cluster ให้ cd เข้าไปที่ /var/www/application_name แล้วสั่งสร้าง configuration file ของ mongrel_cluster
mongrel_rails cluster::configure -e production -p 8000 -N 3 -c /var/www/application_name -a 127.0.0.1 --user mongrel --group mongrel
สร้างแล้วทดลอง start stop ดู
sudo mongrel_rails cluster::start
sudo mongrel_rails cluster::stop
ให้ลองเปิด browser แล้วเรียก localhost:8000, localhost:8001, localhost:8002 ว่าได้ครบหรือเปล่า ในตอนนี้เราไม่สามารถเรียก web โดยตรงจาก IP เพราะต้องการเปิดแค่ localhost เท่านั้น กันคนอื่นเข้ามาเรียกตรงๆ
**Start mongrel when reboot**
ตั้ง config ให้ mongrel cluster ของเราถูกเรียกขึ้นมาใหม่ทุกครั้งที่เปิดเครื่องใหม่
sudo mkdir /etc/mongrel_cluster
sudo ln -s /var/www/application_name/config/mongrel_cluster.yml /etc/mongrel_cluster/application_name.yml
sudo cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster /etc/init.d/
sudo chmod +x /etc/init.d/mongrel_cluster
ทดลองเรียก start stop จาก init.d ดูครับ
sudo /etc/init.d/mongrel_cluster start < Test
sudo /etc/init.d/mongrel_cluster stop < Test
จากนั้นสั่ง update rc.d เพื่อให้เรียก mongrel cluster ทุกครั้ง
sudo /usr/sbin/update-rc.d -f mongrel_cluster defaults
สำหรับ Ubuntu
sudo /sbin/chkconfig --level 345 mongrel_cluster on <- redhat
สำหรับ Linux
2. ติดตั้ง Watch dog เป็น ยามเฝ้า server
=====================
ติดตั้งโปรแกรม monit ก่อน
sudo apt-get install monit
**config monit**
สร้างไฟล์ monitrc ขึ้นมา
sudo mkdir /etc/monit.d
sudo vi /etc/monit.d/mongrel.monitrc
ใส่ config นี้ลงไป
check process mongrel_deployit_8000
with pidfile /var/www/application_name/tmp/pids/mongrel.8000.pid
start program = "/usr/bin/mongrel_rails cluster::start -C /etc/mongrel_cluster/application_name.yml --clean --only 8000"
stop program = "/usr/bin/mongrel_rails cluster::stop -C /etc/mongrel_cluster/application_name.yml --only 8000"
if totalmem is greater than 110.0 MB for 4 cycles then restart
if cpu is greater than 80% for 4 cycles then restart
if 20 restarts within 20 cycles then timeout
group deployit
check process mongrel_deployit_8001
with pidfile /var/www/application_name/tmp/pids/mongrel.8001.pid
start program = "/usr/bin/mongrel_rails cluster::start -C /etc/mongrel_cluster/application_name.yml --clean --only 8001"
stop program = "/usr/bin/mongrel_rails cluster::stop -C /etc/mongrel_cluster/application_name.yml --only 8001"
if totalmem is greater than 110.0 MB for 4 cycles then restart
if cpu is greater than 80% for 4 cycles then restart
if 20 restarts within 20 cycles then timeout
group deployit
check process mongrel_deployit_8002
with pidfile /var/www/application_name/tmp/pids/mongrel.8002.pid
start program = "/usr/bin/mongrel_rails cluster::start -C /etc/mongrel_cluster/application_name.yml --clean --only 8002"
stop program = "/usr/bin/mongrel_rails cluster::stop -C /etc/mongrel_cluster/application_name.yml --only 8002"
if totalmem is greater than 110.0 MB for 4 cycles then restart
if cpu is greater than 80% for 4 cycles then restart
if 20 restarts within 20 cycles then timeout
group deployit
จากนั้นแก้ config อีกสองไฟล์
sudo vi /etc/default/monit
แก้ startup = 1
sudo vi /etc/monit/monitrc
ให้ enable บรรทัดต่อไปนี้
set daemon 120
set logfile syslog facility log_daemon
set httpd port 2812 and
allow localhost # allow localhost to connect to the server and
include /etc/monit.d/*
จากนั้นทดลองสั่ง
sudo /etc/init.d/monit restart
sudo monit restart all -g deployit
sudo monit stop mongrel_deployit_8000
sudo monit start mongrel_deployit_8000
sudo monit status
ลองปิดๆ เปิดๆ ควบคู่ไปกับการดู status เพื่อให้แน่ใจว่ามันปิด มันเปิดได้จริงๆ ใครจะทดลองยิง mongrel ให้ล่ม หรือลอง kill mongrel process ดูก็ได้ครับ จะได้แน่ใจว่ามันล่ม แล้วเปิดขึ้นได้จริงๆ
3. ติดตั้ง NGINX
=======
sudo apt-get install nginx
จากนั้นแก้ไฟล์ /etc/nginx/nginx.conf
sudo vi /etc/nginx/nginx.conf
ใส่ข้อมูลตามนี้
#user deploy;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log logs/error.log debug;
#pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
#tac_nonpush on;
tcp_nodelay on;
#access_log /var/log/nginx/access.log;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
#keepalive_timeout 65;
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
#include /etc/nginx/sites-enabled/*;
upstream mongrel {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
}
server {
listen 80;
server_name example.com;
root /var/www/application_name/public;
index index.html index.htm;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
proxy_pass http://mongrel;
break;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
เราให้ nginx จัดการ static ไฟล์แทน mongrel แต่ถ้าใครต้องการให้ mongrel เป็นคนจัดการสามารถเอา if ต่างๆ ออกได้ตามสะดวก
4. เพื่อให้สมบูรณ์มากขึ้นเราติดตั้งโปรแกรมเอาไว้ monitor การทำงานของ nginx ไว้ด้วยเลย
==============================================
sudo apt-get install rrdtool -y
sudo apt-get install librrds-perl -y
แก้ไฟล์ /etc/nginx/nginx.conf
โดยเพิ่ม location /nginx_status ลงไป
http {
...
server {
listen SOME.IP.ADD.RESS;
...
location /nginx_status {
stub_status on;
access_log off;
allow SOME.IP.ADD.RESS;
deny all;
}
...
}
...
}
ใครอยากจะเพิ่มความปลอดภัยก็ให้ใส่บรรทัด allow และ deny ลงไปด้วย ถ้าไม่คิดจะปิดกั้นก็ลบไปก็ได้ครับ
ทดลองดูก่อนว่า nginx ทำงานเป็นปกติหรือเปล่าหลังจากแก้ config มันแล้ว
# sudo /usr/sbin/nginx -t
2006/04/29 04:24:36 [info] 31676#0: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
2006/04/29 04:24:36 [info] 31676#0: the configuration file /opt/nginx/conf/nginx.conf was tested successfully
#
ถ้าปกติจะขึ้นประมาณนี้
เขียนโปรแกรมง่ายๆ เอาไว้สร้าง graph
sudo mkdir /opt/rrd
sudo mkdir /opt/rrd/html
sudo vi /etc/nginx/rrd_nginx.pl
ตัวโปรแกรมเป็นแบบนี้ ผมก็ลอกมาอีกที จริงๆ เขียน perl ไม่เป็น
#!/usr/bin/perl
use RRDs;
use LWP::UserAgent;
# define location of rrdtool databases
my $rrd = '/opt/rrd';
# define location of images
my $img = '/opt/rrd/html';
# define your nginx stats URL
my $URL = "http://localhost/nginx_status";
my $ua = LWP::UserAgent->new(timeout => 30);
my $response = $ua->request(HTTP::Request->new('GET', $URL));
my $requests = 0;
my $total = 0;
my $reading = 0;
my $writing = 0;
my $waiting = 0;
foreach (split(/\n/, $response->content)) {
$total = $1 if (/^Active connections:\s+(\d+)/);
if (/^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)/) {
$reading = $1;
$writing = $2;
$waiting = $3;
}
$requests = $3 if (/^\s+(\d+)\s+(\d+)\s+(\d+)/);
}
#print "RQ:$requests; TT:$total; RD:$reading; WR:$writing; WA:$waiting\n";
# if rrdtool database doesn't exist, create it
if (! -e "$rrd/nginx.rrd") {
RRDs::create "$rrd/nginx.rrd",
"-s 60",
"DS:requests:COUNTER:120:0:100000000",
"DS:total:ABSOLUTE:120:0:60000",
"DS:reading:ABSOLUTE:120:0:60000",
"DS:writing:ABSOLUTE:120:0:60000",
"DS:waiting:ABSOLUTE:120:0:60000",
"RRA:AVERAGE:0.5:1:2880",
"RRA:AVERAGE:0.5:30:672",
"RRA:AVERAGE:0.5:120:732",
"RRA:AVERAGE:0.5:720:1460";
}
# insert values into rrd database
RRDs::update "$rrd/nginx.rrd",
"-t", "requests:total:reading:writing:waiting",
"N:$requests:$total:$reading:$writing:$waiting";
# Generate graphs
CreateGraphs("day");
CreateGraphs("week");
CreateGraphs("month");
CreateGraphs("year");
#------------------------------------------------------------------------------
sub CreateGraphs($){
my $period = shift;
RRDs::graph "$img/requests-$period.png",
"-s -1$period",
"-t Requests on nginx",
"--lazy",
"-h", "150", "-w", "700",
"-l 0",
"-a", "PNG",
"-v requests/sec",
"DEF:requests=$rrd/nginx.rrd:requests:AVERAGE",
"LINE2:requests#336600:Requests",
"GPRINT:requests:MAX: Max\\: %5.1lf %S",
"GPRINT:requests:AVERAGE: Avg\\: %5.1lf %S",
"GPRINT:requests:LAST: Current\\: %5.1lf %Sreq/sec",
"HRULE:0#000000";
if ($ERROR = RRDs::error) {
print "$0: unable to generate $period graph: $ERROR\n";
}
RRDs::graph "$img/connections-$period.png",
"-s -1$period",
"-t Requests on nginx",
"--lazy",
"-h", "150", "-w", "700",
"-l 0",
"-a", "PNG",
"-v requests/sec",
"DEF:total=$rrd/nginx.rrd:total:AVERAGE",
"DEF:reading=$rrd/nginx.rrd:reading:AVERAGE",
"DEF:writing=$rrd/nginx.rrd:writing:AVERAGE",
"DEF:waiting=$rrd/nginx.rrd:waiting:AVERAGE",
"LINE2:total#22FF22:Total",
"GPRINT:total:LAST: Current\\: %5.1lf %S",
"GPRINT:total:MIN: Min\\: %5.1lf %S",
"GPRINT:total:AVERAGE: Avg\\: %5.1lf %S",
"GPRINT:total:MAX: Max\\: %5.1lf %S\\n",
"LINE2:reading#0022FF:Reading",
"GPRINT:reading:LAST: Current\\: %5.1lf %S",
"GPRINT:reading:MIN: Min\\: %5.1lf %S",
"GPRINT:reading:AVERAGE: Avg\\: %5.1lf %S",
"GPRINT:reading:MAX: Max\\: %5.1lf %S\\n",
"LINE2:writing#FF0000:Writing",
"GPRINT:writing:LAST: Current\\: %5.1lf %S",
"GPRINT:writing:MIN: Min\\: %5.1lf %S",
"GPRINT:writing:AVERAGE: Avg\\: %5.1lf %S",
"GPRINT:writing:MAX: Max\\: %5.1lf %S\\n",
"LINE2:waiting#00AAAA:Waiting",
"GPRINT:waiting:LAST: Current\\: %5.1lf %S",
"GPRINT:waiting:MIN: Min\\: %5.1lf %S",
"GPRINT:waiting:AVERAGE: Avg\\: %5.1lf %S",
"GPRINT:waiting:MAX: Max\\: %5.1lf %S\\n",
"HRULE:0#000000";
if ($ERROR = RRDs::error) {
print "$0: unable to generate $period graph: $ERROR\n";
}
}
**edit cron**
บอก cron ให้สั่ง run script ของเราทุกๆ นาที
$sudo chmod +x /etc/nginx/rrd_nginx.pl
$sudo crontab -e
# m h dom mon dow command
* * * * * /etc/nginx/rrd_nginx.pl
ทดสอบเรียก sudo /etc/nginx/rrd_nginx.pl โปรแกรมจะสร้างรูปขึ้นมาที่ /opt/rrd/html ผมใช้โปรแกรม feh เอาไว้ดูรูป ใครจะเขียน HTML ขึนมาดูรูปก็ได้ครับ
sudo apt-get install feh -y
feh /opt/rrd/html/*.png
เป็นอันเสร็จพิธี ขั้นตอนอาจจะดูยาวครับ แต่ทำจริงๆ แป๊บเดียว ต้องขอบคุณ apt-get มากๆ ช่วยให้งานเร็วขึ้นเยอะทีเดียว
reference: http://wiki.codemongers.com/NginxInstall
reference: http://www.circlingminds.com/advanced-rails/using-nginx-mongrel-rails-on-ubuntu/
blog comments powered by Disqus
สมัครสมาชิก:
ส่งความคิดเห็น (Atom)