最近由于一些原因,想把手上的一个项目从cruby迁移的jruby上来,其间遇到了一些问题和疑惑,写下来与各位分享和探讨。
1. 项目概况
原配置: rails 2.2.2,ruby 1.8.7,oracle 9.2.0.6,部署用nginx+mongrel_cluster
现配置: rails 2.2.2, jruby 1.1.6,jdk 1.6.0_10,oralce 9.2.0.6, 服务器用glassfish v3 (glassfish gem 0.9.2)
2.移植过程中的问题
a. 数据库(字段类型问题)
原来的数据库连接用ruby-oci8 + activerecord-oracle-adapter。因为JRuby不支持c扩展,所以只能改为activerecord-jdbc-adapter + ojdbc14.jar。其实jdbc的更加方便,不需要再安装oracle客户端了。但在实际迁移中却遇到了另一个问题:find_by_sql在cruby中返回的数据集,字段类型可以根据数据库字段类型自 动转换,而不管查询的字段是不是在model中。但在jruby中,此方法返回的数据,如果字段名不在model中,则统一返回字符型。这个差异使代码运行时产生了很多异常。只能手工更改,花费了许多时间。
b. libxml-ruby 与 libxml-jruby
在原项目中需要大量解析xml文件,基于性能的考虑,使用了libxml-ruby库。但此库在jruby中无法使用。在移植开始前,我最烦恼的就是这个问题。如果换用其他库,将会带来很大的代码修改量,且性能上会有所降低。在网上搜索了一下,发现在http://rubyforge.org/projects/libxml-jruby/有一个libxml-jruby的项目,可 里面没有任何代码下载。后来在http://github.com/mguterl/libxml-jruby/tree/master中终于找到了。把代码git clone下来,运行rake gem:install,生成gem 文件。 然后安装。(在parse.rb中的一个bug,定义类的时候没有定义module,导致代码异常,只要加上module定义就行了)。经过测试,这个包的接口与libxml-ruby完全兼容。一行代码都不需要改。而且在速度上也基本相当。真是一个惊喜。
c.性能问题
在这方面JRuby就完全辜负我的期望了,平均速度比ruby 1.8.7 慢了1.5-2倍不等。在生产环境下也要慢1.2-1.5倍。当然这是在window上的测试结果,在linux主机上是不是会有所改善,还没有详细测试。
d.多线程
rails2.2 以后支持多线程了,而jruby的本地线程更是一大优势。所以我自然要测试一下多线程的工作模式了。可在开启多线程后,服务器启动就出错了。经查阅资资料得知,多线程模式中lib目录下的文件不会被自动load,必须要手工require。不过这也没什么,不就是改2行代码吗。但致命的问题是很多插件没法工作了,比如说activescaffold就完全熄火了。看来rails多线程支持还有很长的路要走。
3.总结
没有遇到无法解决的问题。代码也只要稍做修改。性能问题是影响移植的主要障碍。多线程模式还不成熟。
4.疑问
a. 在原来的部署中rails通过mongrel_cluster开启多个进程来响应请求。那在glassfish的方式中,只有一个进程,那请求繁忙时,会不会自动增加rails进程。而且没有开启多线程的情况下,如何同时响应多个请求?
经查阅glassfish文档,已经得到了答案。glassfish会根据配置启动多个rails实例来响应请求。
b.glassfish gem 和 glassfish 服务器在性能上差别有多大?
c.如何优化JRuby on rails的性能?
以上疑问,还请高手解惑。