http://robbin.iteye.com/blog/43228
以及rails部署性能比较的文章。
但是rails3在官网上已经没有关于fastcgi的配置建议了,同时rails3也没有dispatch.fcgi这样类似的东东了。
注定我按照robbin的blog是不会安装成功的了。
但是rack告诉我可以使用fastcgi,
那么sinatra,rails3使用rack肯定也可以使用fastcgi,本着由浅入深的原则开始了我的探索之旅。
而我查到的几篇文章都跟apache相关,那就先从apache开始,然后再尝试lighttpd
安装apache2
sudo aptitude install apache2
apache2的配置文件在/etc/apache2下,一个主文件apache2.conf其他一堆小文件
日志在/var/log/apache2,用下面命令查错很有用
tail -f /var/log/apache2/error.log
查看配置是否有问题可用
apachectl configtest
安装fastcgi模块
sudo aptitude install libapache2-mod-fastcgi libfcgi-dev
一 rack的使用
安装fcgi 和rack gem
gem install fcgi rack
查看 /etc/apache2/sites-available/default看到cgi-bin目录是在 /usr/lib/cgi-bin/
ServerAdmin webmaster@localhost DocumentRoot /var/www Options FollowSymLinks AllowOverride None Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined Alias /doc/ "/usr/share/doc/"Options Indexes MultiViews FollowSymLinks AllowOverride None Order deny,allow Deny from all Allow from 127.0.0.0/255.0.0.0 ::1/128
所以将下面代码保存为hello-world.fcgi放入 /usr/lib/cgi-bin/目录下
#!/home/zc/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby #!/usr/bin/env ruby require 'rubygems' require 'rack' app = Proc.new do |env| Rack::Response.new.finish do |res| res.write "Hello, Rack!" end end Rack::Handler::FastCGI.run app
sudo apachectl start启动apache2
访问 http://localhost/cgi-bin/hello-world.fcgi
可以看到Hello,Rack!说明成功。
ps aux|grep apache2
可见4个apache2进程
root 22351 0.0 0.1 73780 2856 ? Ss 20:10 0:00 /usr/sbin/apache2 -k start www-data 22352 0.0 0.0 73512 1972 ? S 20:10 0:00 /usr/sbin/apache2 -k start www-data 22354 0.0 0.1 297392 3124 ? Sl 20:10 0:00 /usr/sbin/apache2 -k start www-data 22355 0.0 0.1 297208 2412 ? Sl 20:10 0:00 /usr/sbin/apache2 -k start
ps aux|grep cgi
可见一个fastcgi进程管理和一个ruby进程
www-data 22353 0.0 0.1 73512 2108 ? S 20:10 0:00 /usr/sbin/fcgi-pm -k start www-data 22418 0.4 0.6 57272 13724 ? S 20:10 0:00 /home/zc/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby /usr/lib/cgi-bin/hello-world.fcgi
注意#!/usr/bin/env ruby
会引导到/usr/bin/ruby,那个系统ruby我什么都没装,而我使用的rvm,这个问题我还没找到解决办法
暂时使用#!/home/zc/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby
二 sinatra的使用
gem install sinatra
新增配置/etc/apache2/sites-available/sinatra_fcgi
DocumentRoot /home/zc/Sites/sinatra-fcgi Options ExecCGI FollowSymLinks AllowOverride all Order allow,deny Allow from all
将AllowOverride None 修改为AllowOverride all,允许.htaccess文件
链接配置到允许目录,并重启服务
cd /etc/apache2/sites-enabled sudo ln -s ../sites-available/sinatra 001-sinatra
在 /home/zc/Sites/sinatra-fcgi目录下新增.htaccess文件
RewriteEngine On RewriteBase / DirectoryIndex dispatch.fcgi RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]
允许rewrite模块,不然会报Invalid command 'RewriteEngine'错误
cd /etc/apache2/mods-enabled sudo ln -s ../mods-available/rewrite.load rewrite.load
在 /home/zc/Sites/sinatra-fcgi目录下新增dispatch.fcgi文件
#!/home/zc/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby #!/usr/bin/env ruby require 'rubygems' #require 'rack' require 'sinatra' require 'start' Rack::Handler::FastCGI.run Sinatra::Application
在/home/zc/Sites/sinatra-fcgi目录下新增start.rb文件
require 'rubygems' require 'sinatra' get '/' do '你好世界Hello, World!' end
不过这样还是不行,会被吃字,
访问http://localhost 结果显示 "你好世界H",怎么搞都不行,后来
弃用mod-fastcgi改用mod-fcgid就好了,真是晕
三 rails3的使用
参照实例 https://github.com/dre3k/rails3_fcgi
先使用rails server使实例跑起来,由于这个例子没带database.yml我从新建例子中复制一个过来
rake db:migrate
rake db:migrate RAILS_ENV=production
能跑起来后,新增配置 /etc/apache2/sites-available/rails3_fcgi
DefaultInitEnv RAILS_ENV production DocumentRoot /home/zc/Sites/rails3_fcgi/public Options ExecCGI FollowSymLinks AllowOverride all Order allow,deny Allow from all
将配置链接到/etc/apache2/sites-enabled
sudo ln -s /etc/apache2/sites-available/rails3_fcgi /etc/apache2/sites-enabled/001-rails3_fcgi
并将/etc/apache2/sites-enabled下,其他链接删除
mod-fastcgi不认DefaultInitEnv命令,会报下面错误
apache2 Invalid command 'DefaultInitEnv'
替代模块
sudo aptitude install libapache2-mod-fcgid
/etc/apache2/mods-available/fcgid.conf
AddHandler fcgid-script .fcgi FcgidConnectTimeout 20
开启fcgi模块,关闭fastcgi模块
sudo ln -s /etc/apache2/mods-available/fcgid.conf /etc/apache2/mods-enabled/fcgid.conf sudo ln -s /etc/apache2/mods-available/fcgid.load /etc/apache2/mods-enabled/fcgid.load
原始的rails3_fcgi.fcgi有问题
1.由于使用rvm不得不将#!/usr/bin/ruby改为
#!/home/zc/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby
2.require rail3环境要适当修改
修改后文件如下
#!/home/zc/.rvm/rubies/ree-1.8.7-2011.03/bin/ruby #!/usr/bin/ruby #require '../config/environment' require ::File.expand_path('../../config/environment', __FILE__) class Rack::PathInfoRewriter def initialize(app) @app = app end def call(env) env.delete('SCRIPT_NAME') parts = env['REQUEST_URI'].split('?') env['PATH_INFO'] = parts[0] env['QUERY_STRING'] = parts[1].to_s @app.call(env) end end Rack::Handler::FastCGI.run Rack::PathInfoRewriter.new(Rails3Fcgi::Application)
改完后就顺利的跑起来了
public/.htaccess文件正常,无需更改,不过将来放到其他项目中估计要做相应的更改
SetEnv RAILS_RELATIVE_URL_ROOT /rails3_fcgi RewriteEngine On RewriteRule ^(stylesheets/.*)$ - [L] RewriteRule ^(javascripts/.*)$ - [L] RewriteRule ^(images/.*)$ - [L] RewriteRule ^$ index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ rails3_fcgi.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
最后,log/production.log的权限要改一下,不然apache2无法记日志
chmod 666 log/production.log
总结: mod-fastcgi有问题,而且很严重。
mod-fcgid 很好很强大,而且还是国人写的,赞一个。