วันเสาร์, พฤศจิกายน 15, 2551

ติดตั้ง Rails ด้วย Nginx -> 3xMongrel <- Monit

ใน blog ก่อนหน้านี้พูดถึง Nginx -> Mongrel cluster <- Monit ปรากฏว่า monit มันไม่สามารถไปคุมเจ้า mongrel cluster ได้ คาดว่าเป็นเพราะ Mongrel cluster มันเป็น cluster จึงไม่ได้แยกแต่ละตัวออกเป็น process เดี่ยวๆ แบบที่ monit ชอบ ดังนั้นเลยลองวิธีใหม่ แยกมันเป็น 3 ตัวซะเลย ตอนนี้เจ้า monit ควบคุม mongrel อยู่หมัด ผมลอง kill process ดู เจ้า monit ก็ start ขึ้นมาให้ ตอนนี้สั่งปิด/เปิด mongrel จาก monit ได้เลย ขั้นตอนการติดตั้งจะซ้ำกับของเดิมเยอะหน่อย แต่อยากเขียนให้เต็มๆ ครับ เริ่มจาก 1. ติดตั้ง project ของเรา Add new user # สำหรับ ubuntu sudo /usr/sbin/adduser mongrel # สำหรับ redhat ที่ใส่ -r เพราะไม่ต้องสร้าง home ให้ user sudo /usr/sbin/adduser -r mongrel Deploy application sudo mkdir /var/www sudo mkdir /var/www/project sudo chown -R mongrel:mongrel /var/www/project cd /var/www/project su mongrel svn checkout svn://host.com/project/trunk/ --username xxx --password xxx . rake db:create:all rake db:migrate rake db:migrate RAILS_ENV="production" #ทดสอบว่าติดตั้งเรียบร้อยหรือเปล่า ก่อนเริ่มขั้นตอนต่อไป ./script/server 2. ให้แก้ไฟล์ mongrel_rails ให้ลบ PID ออกถ้ามี PID อยู่แล้ว เพราะถ้าไม่ทำเจ้า mongrel_rails จะ error ตอนที่ process ของเราตายโดยทิ้ง PID เอาไว้ แล้วเราพยายาม start mongrel ขึ้นมา มันจะฟ้องว่ามี PID อยู่แล้ว และไม่ยอม start ให้เรา สั่ง edit mongrel_rails ใครถนัด editor ตัวไหนก็ใช้ตามสะดวกนะครับ sudo vi /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails #บางทีก็อยู่ที่นี่ sudo /var/lib/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails แทนที่บรรทัดนี้ if File.exist? defaults[:pid_file] log "!!! PID file #{defaults[:pid_file]} already exists. Mongrel could be running already. Check your #{defaults[:log_file]} for errors." log "!!! Exiting with error. You must stop mongrel and clear the .pid before I'll attempt a start." exit 1 end ด้วยบรรทัดนี้ if File.exist? defaults[:pid_file] # mongrels that crash can leave stale PID files behind, and these # should not stop mongrel from being restarted by monitors... pid = File.new(defaults[:pid_file]).readline unless `ps -ef | grep #{pid} | grep -v grep`.length > 0 # use "ps ax" for freebsd log "!!! PID file #{defaults[:pid_file]} exists, but is stale, and will be deleted so that this mongrel can run." File.delete(defaults[:pid_file]) else log "!!! PID file #{defaults[:pid_file]} already exists and the process id referred to in it is running. This mongrel is probably already running. #{defaults[:log_file]} for errors. EXITING." exit 1 end exit 1 end 3. เตรียม config สำหรับ mongrel ทั้ง 3 ตัว sudo vi /var/www/project/config/mongrel_8000.yml --- user: mongrel cwd: /var/www/project log_file: log/mongrel.8000.log port: "8000" environment: production group: mongrel address: 127.0.0.1 pid_file: tmp/pids/mongrel.8000.pid daemon: true สร้างไฟล์นี้อีกสองไฟล์ แต่เปลี่ยนจาก 8000 เป็น 8001 และ 8002 สำหรับคนที่ลง mongrel cluster ไปแล้ว แถมสั่งให้มัน start ตอน boot ด้วย ต้องไปเอาออกก่อนครับ เพราะต่อไปเราจะให้ monit เป็นคน start ให้ทั้งหมด ผมใช้วิธีลบ ไฟล์ /etc/mongrel_cluster/application_name.yml ออกไป ทดสอบว่า server ของเราทำงานโดยสั่ง sudo /usr/bin/mongrel_rails start -C /var/www/project/config/mongrel_8000.yml จากนั้นทดลองสั่ง ps -aux | grep mong ถ้ามี process 8000 ของเราขึ้นมาแสดงว่าเรียบร้อย ถ้าไม่ขึ้นให้ลองไปดู log ที่ /var/www/project/log/mongrel.8000.log จากนั้นลองสั่ง stop ดูด้วยคำสั่ง sudo /usr/bin/mongrel_rails stop -P /var/www/project/tmp/pids/mongrel.8000.pid ถ้าไม่ได้ให้ลองดู log เหมือนเดิม ถ้าได้ก็ไปขั้นตอนต่อไปได้เลย 4. ติดตั้ง Watch dog ที่ชื่อ monit ติดตั้ง monit (ถ้าใครไม่มี apt-get ใช้ก็ลองประยุกต์ใช้ทางอื่นดูนะครับ) sudo apt-get install monit จากนั้นตั้งค่าให้ monit sudo mkdir /etc/monit.d sudo vi /etc/monit.d/mongrel.monitrc ใส่ config ตามนี้ check process mongrel_8000 with pidfile /var/www/project/tmp/pids/mongrel.8000.pid group mongrel start program = "/usr/bin/mongrel_rails start -C /var/www/project/config/mongrel_8000.yml" stop program = "/usr/bin/mongrel_rails stop -P /var/www/project/tmp/pids/mongrel.8000.pid" if failed host 127.0.0.1 port 8000 protocol http and request "/" then alert 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 3 restarts within 5 cycles then timeout check process mongrel_8001 with pidfile /var/www/project/tmp/pids/mongrel.8001.pid group mongrel start program = "/usr/bin/mongrel_rails start -C /var/www/project/config/mongrel_8001.yml" stop program = "/usr/bin/mongrel_rails stop -P /var/www/project/tmp/pids/mongrel.8001.pid" if failed host 127.0.0.1 port 8001 protocol http and request "/" then alert 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 3 restarts within 5 cycles then timeout check process mongrel_8002 with pidfile /var/www/project/tmp/pids/mongrel.8002.pid group mongrel start program = "/usr/bin/mongrel_rails start -C /var/www/project/config/mongrel_8002.yml" stop program = "/usr/bin/mongrel_rails stop -P /var/www/project/tmp/pids/mongrel.8002.pid" if failed host 127.0.0.1 port 8002 protocol http and request "/" then alert 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 3 restarts within 5 cycles then timeout ถ้าเจ้า monit เจออะไรผิดพลาด ตามที่เขียนใน config มันจะ restart ให้ทันที อันนี้ชอบมั๊กๆ แต่เปิดใช้มาหลายวัน มันยังไม่เคย restart เองเลยครับ เสถียรมาก มีแต่ผมสั่งมัน restart เอง คงเพราะ ผู้ใช้ยังไม่คุ้นเลยยังยิงกันไม่ถึงตาย แก้ไฟล์ monit ให้มัน start ตอน boot เครื่อง sudo vi /etc/default/monit startup=1 จากนั้นเอา comment ของไฟล์ monitrc ออกตามนี้ sudo vi /etc/monit/monitrc 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/* ทดสอบการทำงานของ monit ตามนี้ครับ สั่ง restart, sudo shutdown -r now เมื่อเปิดมาตอนแรกให้รอ 5-10 นาที จากนั้นลอง sudo monit status ตัว monit ควรจะ start mongrel ให้เราทั้งสามตัว ทดลอง ps -aux | grep mong ดู process ทั้งหมดของ mongrel ทดลอง kill 1 process รอ 5-10 นาที ทดลอง ps -aux | grep mong ดูว่า mongrel start ขึ้นมาให้เราหรือเปล่า แล้วสั่ง sudo monit status ดูว่า monit รับรู้การขึ้นมาหรือยัง ถ้าขึ้นมาครบทั้ง 3 ตัวเป็นอันว่าติดตั้ง mongrel และ monit สำเร็จ คำสั่งที่ใช้บ่อยบน monit มีดังนี้ครับ # restart monit ถ้ามันหือ sudo /etc/init.d/monit restart #restart mongrel ยกฝูง sudo monit restart all -g mongrel #start/stop บางตัว sudo monit stop mongrel_8000 sudo monit start mongrel_8000 #ดู status sudo monit status #force ให้ monit ตรวจสอบการทำงานของ process ที่มันดูอยู่ sudo monit validate 5. ติดตั้ง NGiNX sudo apt-get install nginx แก้ config ของไฟล์ 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 project.com; root /var/www/project/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; } } } restart NGiNX ด้วยคำสั่ง sudo /etc/init.d/nginx restart จากนั้นลองเข้าผ่าน web ดูครับ ว่าเปิดได้หรือเปล่า ถ้าได้ก็จบครับ ขั้นต่อไปเป็นของแถม ทำเผื่อเอาไว้ตอนมีปัญหาจะได้เข้ามาดู 6. ติดตั้งตัว monitor ให้ NGiNX sudo apt-get install rrdtool librrds-perl -y sudo vi /etc/nginx/nginx.conf เพิ่ม location status ลงไประหว่าง http และ server http { ... server { listen SOME.IP.ADD.RESS; ... location /nginx_status { stub_status on; access_log off; allow SOME.IP.ADD.RESS; deny all; } ... } ... } ทดสอบว่า script NGiNX ของเรายัง ok อยู่ # 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 สร้างที่อยู่ให้ output file sudo mkdir /opt/rrd sudo mkdir /opt/rrd/html sudo vi /etc/nginx/rrd_nginx.pl ไฟล์ rrd_nginx.pl เอาได้ที่ apirak.com/downloads/rrd_nginx.pl อย่าลืมสั่งให้ rrd_nginx.pl กลายเป็น execute file ด้วย chmod +x /etc/nginx/rrd_nginx.pl จากนั้น edit ให้ cron เรียก rrd_nginx.pl ทุกๆ นาที sudo crontab -e # m h dom mon dow command * * * * * /etc/nginx/rrd_nginx.pl เมื่อโปรแกรมทำงานจะมีรูปขึ้นมาที่ /etc/opt/rrd/html สามารถเข้าไปดูได้ วินาทีนี้ผมยังไม่ได้สร้าง HTML สำหรับดู เลยทำแค่ ใช้ feh ในการดู sudo apt-get install feh -y feh /opt/rrd/html/*.png ถ้ามีกราฟขึ้นก็แสดงว่าโปรแกรมทำงานได้แล้ว และถ้ากราฟมีขึ้นๆ ลงๆ ก็แสดงว่าสมบูรณ์ละแล้วครับ :) Reference ( บางแหล่งก็ลืมไปแล้วครับ จดไว้ประมาณนี้) http://codesnippets.joyent.com/tag/mongrel http://www.howtoforge.com/server_monitoring_monit_munin http://www.circlingminds.com/advanced-rails/using-nginx-mongrel-rails-on-ubuntu/ http://wiki.codemongers.com/NginxInstall http://groups.google.com/group/thinking-sphinx/browse_thread/thread/a7a11ab1c98f5593 http://mkaz.com/ref/unix_cron.html
blog comments powered by Disqus