Ruby Web开发的几个途径

分享RubyWeb by 达达 at 2007-03-05

昨天写了《Windows环境使用mongrel运行Ruby on Rails》记录简陋配置RoR的方法。基于Rails框架做Web开发只是一种比较高效的途径,但不是必须的,Ruby还有另外一些做Web开发的途径。

使用CGI方式当然是最基本的了。在IIS下设置Ruby的CGI和Perl一样,先添加'.rb'扩展的应用程序映射,然后分配目录的执行权限。IIS中添加文件影射时找到ruby.exe然后在路径字符串后面加上参数,像这样:c:\ruby\bin\ruby.exe "%s" %s ,然后给IIS默认帐户分配ruby目录的执行权限,配置完就可以在IIS下执行.rb页面了。

以CGI模式运行时,你可以使用print或者puts输出整个页面。不过Ruby已经封装了一个CGI类,帮我们简化操作。CGI类的用法类似这样:

#!usr/bin/ruby

require 'cgi'

cgi = CGI.new("html3")

cgi.out {
    cgi.html {
        cgi.head { cgi.title {"CGI test page"} }
        cgi.body {
            cgi.h1 { "Hello, Ruby CGI!!!" }
        }
    }
}

另外CGI类还封装了Cookie和Session等功能,具体内容大家可以参考Ruby的文档。

CGI有一个很大的问题就是性能。每一个用户请求都会启动一个新的Ruby进程,这样内存会占用很大,假设一个进程10M内存,100个用户并发的系统就需要1G的内存,据说一个正常网站运行的时候单个Ruby进程内存使用远不止10M了,是不是挺可怕。根据《Programming Ruby》上的介绍,mod_ruby可以在Apache下改善Ruby的性能,它的原理好像是mod_ruby让Apache具有Ruby解释器的能力,而不需要每个请求都启动一个Ruby解释器进程。但是这种方式存在另一种问题,运行的应用程序多的时候可能会出现库冲突,我不知道具体是什么原因造成,只是书上这么描述。如果你担心发生这种情况,那就需要使用FastCGI协议,FastCGI使用了自己的算法来响应CGI请求,FastCGI对所有CGI类型的程序都适用,这就是很多网上教程都是《FastCGI + Apache + XXX脚本》的原因。还好IIS下也有FastCGI的工具 :-)

除了CGI以外,还有另外一种方式,可以运行Ruby的Web程序,不过是以Servlet形式运行。

Ruby捆绑了一个叫WEBrick的HHTTP服务器工具,它能让你用Ruby自己假设一个独立的HTTP服务器,有的神奇 :-)

WEBrick的用法很简单,下面是一个实验性的Servlet:

#!usr/bin/ruby

require 'webrick'
include WEBrick

#定义一个Servlet类继承自抽象Servlet类,并实现do_GET方法
class HelloServlet < HTTPServlet::AbstractServlet

  def do_GET(req, res)
    res['Content-Type'] = "text/html"
    res.body = "Hello!!"
  end

end

s = HTTPServer.new(:Port => 8084)

s.mount("/hello", HelloServlet)

trap("INT"){ s.shutdown }

s.start

在命令行下用Ruby执行这个脚本文件,将会在8084端口启动一个HTTP服务器。

D:\>ruby webserver.rb
[2007-05-05 10:50:52] INFO  WEBrick 1.3.1
[2007-05-05 10:50:52] INFO  ruby 1.8.6 (2007-03-13) [i386-mswin32]
[2007-05-05 10:50:52] INFO  WEBrick::HTTPServer#start: pid=4052 port=8084

在浏览器中请求 http://localhost:8084/hello ,服务器将会执行do_GET方法,并返回结果。

要结束服务器程序,在命令行下按Ctrl + C就可以了,上面代码中的 trap("INT"){ s.shutdown } 确保程序中断时服务器正常关闭。

[2007-05-05 10:57:16] INFO  going to shutdown ...
[2007-05-05 10:57:16] INFO  WEBrick::HTTPServer#start done.

WEBrick模式运行的程序一启动就挂住一个Ruby进程,直到服务器程序被关闭,这样应该不会出现CGI中一个请求一个Ruby进程的问题。但是不知道并发性能会不会很差,有空我再用压力测试工具测一下。具体的WEBrick信息可以到www.webrick.org查。