分类
原创作品 技术

IronRuby+IIS+Typo的尝试和对Ruby跨平台性的质疑

一开始,我只是想找一个当前博客程序的替代品。而我发现了Typo这样令人激动的基于RoR的开源博客程序,跃跃欲试想把Typo运行在IIS + IronRuby + IronRuby.Rack上。

Typo 5.5依赖于Ruby 1.8.7 + Rails 2.3.8。IronRuby 1.0基本兼容Ruby 1.8.6,我想问题应该不大。

XP系统,一个崭新的IronRuby 1.0安装版。安装Rails:

igem install rails -v 2.3.8

为了方便,打算使用SQLite数据库,在IronRuby下,sqlite3-ruby这样的gem是不能用的,需要用sqlite3-ironruby这样的替代方案。早在这一步我就应该注意到一些问题了,但我当时没有在乎:

igem install sqlite3-ironruby

尝试了几次RubyGems直接安装Typo都失败了,我自己从ZIP里解压了一份Typo 5.5。

在config目录下创建database.yml:

production:
  adapter: sqlite3
  database: db/typo.db
  timeout: 5000

然后执行rake操作DB:

rake db:create RAILS_ENV=production
rake db:migrate RAILS_ENV=production

问题来了,rake报告有一系列需要依赖的gem没有安装。那就让它装:

rake gems:install

找不到gem命令,没问题,把igem.bat复制一份命名为gem.bat。

再执行,大部分安装都成功了,除了json、bluecloth 2.0.5和RedCloth 4.2.2。报错都在编译Native Extension上。

去RubyForge上找齐了这三个的Windows预编译版本,再用RubyGems单独从本地安装,成功。

再尝试之前的DB Migrate操作,rake却依然报告找不到两个gem依赖:

Missing these required gems:
  bluecloth  ~> 2.0.5
  RedCloth  ~> 4.2.2

经过各种google,终于在IronRuby官网(Documentation –> Real Ruby Applications –> RubyGems –> Native gems)上得知了一个噩耗:

Native extensions are not supported by IronRuby. Currently, there is no known way of avoiding native gems. When you install gems, you will have to manually exclude gems with win32 in the name.

本来就是希望跨平台采用了IronRuby,结果这又出现平台依赖的要素了。这不得不令我质疑之前自己对Ruby跨平台性的认识。

现在的疑问是Native Extension在Ruby开源界占有多大比重?IronRuby在缺少此类支持的情况下,能为我带来多少好处?

分类
原创作品 技术

Ruby/RoR on IIS6.1 via IronRuby and .NET3.5

标题足够明了了。

Ruby是个好东西。第一次接触Ruby的语法,就被它的简洁和动态特征吸引了。RoR (Ruby on Rails) 具体有多好我倒不是很关心,对我来说Ruby的意义更在于扩展了server-side的语言和技术体系。

市面上主流的web开发技术确实很多。自己的工作内容是J2EE,但业余兴趣也做这个就有些枯燥了;我对ASP.NET情有独钟,无奈其升级换代太快,技术体系也偏庞大;PHP一直没有机会深入学习,一直觉得它的语法不够清爽。

在给定browser端的技术方案是Flex、Ajax或者HTML5的前提下,其实server端是什么技术区别也不会太大。如果这个技术从语言层面即可以面向对象又有足够动态特性,从框架层面可以保持轻量又足够灵活,那就是一个优秀的选择。Ruby上基于Rack有Sinatra可以轻松编写RESTful Service,目前对我已足够了。

跨平台是我选Ruby的另一个理由。这里所说的跨平台是指可以在多种虚拟机上运行。已知的有可以运行在Java虚拟机上的JRuby,和运行在.NET虚拟机上的IronRuby。这对我来说意味着在纯Ruby环境下开发的应用可以很轻松的迁移到Java平台或者.NET平台。或者再说明白一点,国内还没见到比较靠谱的Ruby虚拟主机服务商,而.NET在国内则满地都是,还便宜,而且什么时候Java主机大众化了,我还可以把应用迁移过去。

回到方案。要点是DIY编译一下IronRuby.Rack。基本过程参考如下视频即可:
http://www.iamnotmyself.com/2010/04/22/RunningRailsInIIS7WithIronRubyRack.aspx

我的开发编译环境比较老,但经过反复尝试也成功部署了。

1、下载并安装IronRuby。http://www.ironruby.net/Download ,我下载了其中1.0 for .NET2.0(据说for .NET4.0的版本会更快)的Windows Installer,这个发行版本内置了Ruby 1.8及其周边。安装至C:\IronRuby\,安装程序会帮我把环境变量之类的设置好。

2、在Ruby上安装Rack、数据库和RoR。 参考http://www.ironruby.net/Documentation/Real_Ruby_Applications/Rails

  • Rack和Rails,在命令行里执行:
    > igem install rake rails --no-rdoc --no-ri
    Successfully installed rake-0.8.7
    Successfully installed activesupport-2.3.5
    Successfully installed activerecord-2.3.5
    Successfully installed rack-1.0.1
    Successfully installed actionpack-2.3.5
    Successfully installed actionmailer-2.3.5
    Successfully installed activeresource-2.3.5
    Successfully installed rails-2.3.5
    8 gems installed
  • 数据库选了SQLite3:
    > ir -S gem install sqlite3-ironruby --no-ri --no-rdoc
    Successfully installed sqlite3-ironruby-0.1.1
  • 随便建个目录,然后自动生成RoR的应用:
    > ir -S rails IronRubyOnRails
          create
          create  app/controllers
          create  app/helpers
          create  app/models
          create  app/views/layouts
          create  config/environments
          create  config/initializers
          ......
  • 利用内置Web服务器测试RoR,http://localhost:3000 能正常显示页面即成功:
    > cd IronRubyOnRails
    > ir script\server
    => Booting WEBrick
    => Rails 2.3.5 application starting on http://0.0.0.0:3000
    => Call with -d to detach
    => Ctrl-C to shutdown server
    [2009-04-22 13:55:50] INFO  WEBrick 1.3.1
    [2009-04-22 13:55:50] INFO  ruby 1.8.6 (2009-03-31) [i386-mswin32]
    [2009-04-22 13:55:50] INFO  WEBrick::HTTPServer#start: pid=10848 port=3000

3、下载IronRuby的源代码。http://github.com/ironruby/ironruby/ ,v1.0-rtm或者稍新点的都可以,没有Git直接下载zip包也可以。老实说只会用到其中ironruby/Hosts/IronRuby.Rack目录下的内容。

4、启动Visual Studio 2008(我用的是Visual Web Developer Express 2008),把刚才源代码中ironruby/Hosts/IronRuby.Rack中的IronRuby.Rack.sln作为解决方案打开,会报几个错,不过没关系。

5、查看各项目的属性,检查编译.NET版本是否是3.5。从IronRuby的安装路径中找到以下DLL库,然后添加到IronRuby.Rack工程的引用中。

IronRuby.dll
IronRuby.Libraries.dll
IronRuby.Libraries.Yaml.dll
Microsoft.Dynamic.dll
Microsoft.Scripting.Core.dll
Microsoft.Scripting.Debugging.dll
Microsoft.Scripting.dll
Microsoft.Scripting.ExtensionAttribute.dll

 

6、修改各web项目的web.config。以IronRuby.Rack.Example为例,修改LibraryPaths和GemPath值,把原路径都改到IronRuby的安装路径里去。

7、给IronRuby的安装目录加入NETWORK SERVICE用户组的可读权限,然后在IDE环境中运行IronRuby.Rack.Example(或者IronRuby.Rails.Example)。如果目标IIS版本低于7,如Window Server 2003的IIS6.1,则需要修改浏览器URL来让请求通过ASP.NET处理,如加入后缀.aspx或者.ashx。当然也可以调整IIS的配置使得ASP.NET引擎处理所有请求。结果类似下图即为通过。

ironruby_on_iis

8、部署至远程IIS。需要编译一个发行版的IronRuby.Rack.dll,把IronRuby.Rack项目的生成方式改为release,再生成一次即可。注意这里的目标runtime是.NET3.5,如果用.NET2.0的话编译是很难通过的。把第5步中的所有DLL与这个DLL一起拷贝到远程IIS虚拟目录的bin目录下。

本机编译的发行版本(.NET3.5) IronRuby.Rack

9、上传IronRuby安装路径中的Lib目录至同一远程IIS虚拟目录中。调整web.config第6步中的路径,然后与config.ru、app.rb一起上传至同一目录。

10、浏览器中按第7步的方式测试。第一次加载很慢,以后就快很多了。URL要加后缀这点非常麻烦,部署在Windows Server 2008 + IIS7上应该可以解决(理论上就可以用for .NET4.0的方案了)。

欢迎来到Ruby的世界。