ทดลองมาหลาย 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;
- $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($){
- 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) {
- }
- 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) {
- }
- }
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/
| Attachment | Size |
|---|---|
| web_solution.png | 35.44 KB |
Post new comment