しまてく

学んだ技術を書きためるブログ

さくらサーバーでRailsを高速に動作させる方法

さくらサーバー × Ruby on Rails × gateway.cgi

通常RoRはfast-cgiを使って高速化するのが常なようですが、残念ながらさくらサーバーは
fast-cgiを許してくれません。。。*1


なのでgateway.cgiというものを代わりに使うと幸せになれるようです。
動作的には、

  1. 初回アクセス時に半常駐プログラムを起動、処理。
  2. 2回目以降は半常駐プログラムでの処理。

という、なんとなくさくらサーバーでは使えなさそうなcgiですが、ひとつ仕組みがあります。


というのも実は単純で、デフォルトでは90秒アクセスがないと自動的に終了してくれるので、
さくらの環境で使えるだろうと思ってます。*2 *3

railsfcgiをインストールする


%gem install rails
%gem install fcgi
Building native extensions. This could take a while...
ERROR: Error installing fcgi:
ERROR: Failed to build gem native extension.

/home/username/local/bin/ruby extconf.rb install fcgi
checking for fcgiapp.h... no
checking for fastcgi/fcgiapp.h... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/home/username/local/bin/ruby
--with-fcgi-dir
--without-fcgi-dir
--with-fcgi-include
--without-fcgi-include=${fcgi-dir}/include
--with-fcgi-lib
--without-fcgi-lib=${fcgi-dir}/lib


Gem files will remain installed in /home/username/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7 for inspection.
Results logged to /home/username/local/lib/ruby/gems/1.8/gems/fcgi-0.8.7/ext/fcgi/gem_make.out

あら、失敗。。


いろいろとググっていると依存関係がうんぬんということで「--include-dependencies」をつけるといいらしいです。

再チャレンジ


%gem install fcgi --include-dependencies
INFO: `gem install -y` is now default and will be removed
INFO: use --ignore-dependencies to install only the gems you list
Building native extensions. This could take a while...
ERROR: Error installing fcgi:
ERROR: Failed to build gem native extension.

/home/username/local/bin/ruby extconf.rb install fcgi --include-dependencies
checking for fcgiapp.h... no
checking for fastcgi/fcgiapp.h... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/home/username/local/bin/ruby
--with-fcgi-dir
--without-fcgi-dir
--with-fcgi-include
--without-fcgi-include=${fcgi-dir}/include
--with-fcgi-lib
--without-fcgi-lib=${fcgi-dir}/lib


Gem files will remain installed in /home/username/local/lib/gem/gems/fcgi-0.8.7 for inspection.
Results logged to /home/username/local/lib/gem/gems/fcgi-0.8.7/ext/fcgi/gem_make.out

か、変わらん。。


再度ググっていると別の記事を見つけたので再チャレンジ!

ラボ日記(http://blog.lacom.co.jp/hnd/item/49)を参考に。


%cd $HOME/local/src
# fcgiのソースをダウンロード
%wget http://fastcgi.com/dist/fcgi-2.4.0.tar.gz
%tar zxvf fcgi-2.4.0.tar.gz
%cd fcgi-2.4.0
%./configure --prefix=$HOME/local
%make
%make install

# 再々チャレンジ
%gem install fcgi -- --with-fcgi-include=$HOME/local/include --with-fcgi-lib=$HOME/local/lib
Building native extensions. This could take a while...
Successfully installed fcgi-0.8.7
1 gem installed

おお!入った!!


一応確認。


%gem list

 *** LOCAL GEMS ***

actionmailer (2.1.1)
actionpack (2.1.1)
activerecord (2.1.1)
activeresource (2.1.1)
activesupport (2.1.1)
fcgi (0.8.7)
login_generator (1.2.2)
mysql (2.7)
rails (2.1.1)
rake (0.8.2)
rubygems-update (1.2.0)
sources (0.0.1)

うしうし、ちゃんと入ってるね。

gateway.cgiRailsのプロジェクトに適応する


#Rails のインストールディレクトリを一時的に環境変数に入れる。(めんどいから)
%setenv RAILS_DIR /home/username/local/lib/ruby/gems/1.8/gems/rails-2.1.1/

# 新しいrailsアプリケーションを作る
$ rails admin
$ cd admin

# admin/log/以下に[drb_gateway]ディレクトリを作って、CGIのプロセスが書き込めるようにする。
$ mkdir log/drb_gateway
$ chmod 777 log/drb_gateway

# スクリプトをコピーしてくる
$ cp $RAILS_DIR/dispatchers/gateway.cgi public/
$ cp $RAILS_DIR/lib/commands/ncgi/listener script/
$ cp $RAILS_DIR/lib/commands/ncgi/tracker script/
$ chmod 755 public/gateway.cgi

# パッチを当てる
# パッチはFTPなどでadmin/の下に置いてください。
$ patch -p1 < gateway.patch

パッチは↓です。


diff -urN src/public/gateway.cgi new/public/gateway.cgi
--- src/public/gateway.cgi Tue Sep 23 19:00:17 2008
+++ new/public/gateway.cgi Tue Sep 23 19:00:21 2008
@@ -1,7 +1,6 @@
-#!/usr/local/bin/ruby
+#!/usr/bin/env ruby

require 'drb'
-
# This file includes an experimental gateway CGI implementation. It will work
# only on platforms which support both fork and sockets.
#

diff -urN src/script/listener new/script/listener
--- src/script/listener Tue Sep 23 19:00:18 2008
+++ new/script/listener Tue Sep 23 19:00:22 2008
@@ -1,7 +1,10 @@
-#!/usr/local/bin/ruby
+#!/usr/bin/env ruby

require 'stringio'
require 'fileutils'
+
+require 'rubygems'
+gem 'fcgi'
require 'fcgi_handler'

def message(s)
@@ -14,6 +17,8 @@
self.env_table = env_table
self.stdinput = input || StringIO.new
self.stdoutput = output || StringIO.new
+ $stdin = self.stdinput
+ $stdout = self.stdoutput
super()
end

diff -urN src/script/tracker new/script/tracker
--- src/script/tracker Tue Sep 23 19:00:18 2008
+++ new/script/tracker Tue Sep 23 19:00:22 2008
@@ -1,4 +1,4 @@
-#!/usr/local/bin/ruby
+#!/usr/bin/env ruby

require 'drb'
require 'thread'

public/.htaccess を書き換え

# [dispatch.cgi]となっているところを[gateway.cgi]に書き換える。

# うちの環境ではこんな感じ。
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

RewriteRule ^(.*)$ gateway.cgi [QSA,L]

結果

before


Processing Edit::EditorController#category_edit (for 59.146.184.18 at 2008-09-23 20:25:51) [GET]
Completed in 0.02856 (35 reqs/sec) | DB: 0.02058 (72%) | 302 Found http://hoge.jp/admin/edit/editor/category_edit

Processing Edit::CategoryController#index (for 59.146.184.18 at 2008-09-23 20:25:53) [GET]
Completed in 0.12254 (8 reqs/sec) | Rendering: 0.01468 (11%) | DB: 0.04479 (36%) | 200 OK http://hoge.jp/admin/edit/category

after


Processing Edit::EditorController#category_edit (for 59.146.184.18 at 2008-09-23 20:21:09) [GET]
Completed in 0.00375 (266 reqs/sec) | DB: 0.00315 (83%) | 302 Found http://hoge.jp/admin/edit/editor/category_edit

Processing Edit::CategoryController#index (for 59.146.184.18 at 2008-09-23 20:21:09) [GET]
Completed in 0.02184 (45 reqs/sec) | Rendering: 0.00640 (29%) | DB: 0.01307 (59%) | 200 OK http://hoge.jp/admin/edit/category


なんと5倍〜10倍近く早くなりました!
実際にアクセスしてみてもはっきり体感できるくらいの応答速度になりました!


これはいい!

*1:fast-cgiという訳ではなく、常駐するプログラム全般が禁止

*2:あくまでcimadaiの判断です><

*3:怒られたら戻さないとね。