rails3项目解析之二——rails基础
rails3项目解析之2——rails基础
rails3项目解析之1——系统架构
rails3项目解析之3——redis
rails 3.0是2010年8月份发布的。迄今为止,3.0已历经多个tiny版到了3.0.8。3.1已经放出rc4,看起来离正式版已为期不远。相对于2系,3系还是有一些令人惊喜的变化,而且在架构上也规范和严整了许多。3.1中更是又加入了几个颇为有趣的特性。我们的项目一直都是紧跟rails新版,很欣慰能够毫无道德压力地做一个喜新厌旧常换常新的男人。但什么都追新也吃了不少小苦头,不过仍然死不悔改,大家都在坐等3.1发布试吃。
更多关于rails3的新特性,网上一抓一把,需求和欲望比较强烈的同学可自行解决,在此不再赘述。下面主要说一下我们这个项目。因为项目不大,而且第一期没有太多用户互动的内容,所以涉及到的知识范畴比较小,都是些基础的东西。
1、目录结构
除那些默认目录之外,我们在项目中又另外加了一些自定义的目录来做不同的事情。
1.1 errros/。在app/目录之下,内容是各种自定义的XxxError类。使用异常机制能够使得代码更加清晰,流程语义更准确,更好地实现模块化的程序结构。
1.2 validators/。在app/目录之下,内容是继承自ActiveModel::EachValidator的各种验证类。使用自定义验证类能够使代码更加简洁,复用性更强。如:
这里面就使用了三个自定义验证类:可用、合法、符合用户名规则。
1.3 workers/。在app/目录之下,内容是resque任务的定义类。
1.4 其它和项目相关的目录。比如在项目根目录下,我们加了一个monitor/目录,里面是resque和redis的监控脚本。因为监控脚本在概念上属于项目外层,所以放到根目录下面,不隶属于app/。
2、使用组件
2.1 rails 3.0.8。这个没什么可说的,用蜂蜜,川贝,桔梗,加上天山雪莲配制而成,实在是居家旅行、杀人灭口之必备良药。不过我们在3.0.8上吃了点苦头,丫把safe_buffer设置为不可改动,结果页面片段缓存的cache方法中的slice!触犯了这个禁条,网站首页直接挂掉。还好,发现这个问题是晚上10点,没有造成太多损失。3.0.9已经修正了这个大bug,请各位不必多虑。
2.2 mysql2。舍弃了mysql驱动,使用mysql2。不过要设置为'< 0.3.0',0.3版的mysql2是配合rails 3.1的。
2.3 ruby-oci8、activerecord-oracle_enhanced-adapter。连接公司oracle数据库取行情数据的。还需要安装oracle的instant client,把安装目录添加到/etc/ld.so.conf.d里,然后ldconfig。有想用oracle的可做参考。
2.4 nokogiri、yajl-ruby。正好项目中也要用到nokogiri,所以就干脆替代了rails自带的xml和json解析器。
2.5 authlogic、cancan。比较了一下authlogic和devise,感觉各有利弊。因为authlogic对于namespace的处理比较灵活,而且也利于第三方身份验证的扩展,比较适合我们的需求,所以最后选了authlogic。cancan对于不是很复杂的权限验证,也差不多够用了。更细粒度的权限系统,恐怕就得根据需求自己定制了。
2.6 acts_as_list、acts_as_state_machine、will_paginate。前两个不解释。will_paginate的rails3版本已经很久没更新了,不知道作者是恋爱了还是失业了。kaminari是个很好的替代,只是有些功能还没完善,是否可以完全替换will_paginate有待论证。
2.7 ckeditor、paperclip、rmagick。其实富文本编辑器已经有不少了,比ckeditor好的也不乏其数。不过具备相配合的成熟gem的,恐怕目前还只有ckeditor。如果不嫌麻烦,可以找个更好的编辑器,直接挂上去用,或者自己写gem挂到rails上。
2.8 redis-store、SystemTimer、mongoid。使用redis作为默认的rails缓存,SystemTimer是redis client等几个gem要求使用的,ruby 1.8.7的timeout不可靠,我见到的几个gem的作者都强烈建议使用SystemTimer。mongoid支持rails3,所以就没用mongo_mapper。mongoid配置简单,语法很不错,功能比较强大。
2.9 resque、resque-scheduler、eventmachine。研究过twitter当初做的starling和workling,勉强能用,但配置很复杂,而且很久不更新了,就始乱终弃之。resque套件另行开文,在此不多说。
2.10 formtastic。formtastic号称是语义表单,实际用起来还是挺不错的,erb上的代码简洁多了,学习曲线也不高,一看即会。而且formtastic扩展性非常好,我们修正了和ckeditor的接口,还自定义了日期选择(date_picker on jquery)、日期选择组(date_selects)和验证码(captcha)控件。
2.11 client_side_validations。这年头网站上没个客户端动态验证,出门都不好意思跟人家打招呼。它能够直接使用model中定义的验证规则,DRY得很。而且能够和formtastic无缝整合。另外也很好扩展,我们利用回调加上了动态验证时的绿对号红叉号的小图片。
2.12 capistrano、capistrano-ext。代码发布管理的。如果你有不同开发环境的十几台服务器需要依次发布代码,就知道这东西有什么用处了。同样,这部分将另行开文。
3、配置
虽然说“约定优于配置”,但也不能没配置。不过如果只要配置配置就能搞定,总比写代码好多了。
3.1 自定义配置。项目中要使用到一些自定义的配置,比如oracle数据库的地址、redis服务器地址等等,而且开发环境和产品环境的还不一样。我们在config/目录下放了一个configuration.yml,里面区分出不同的environment,各个env下写入各自的配置。rails初始化的时候读取该yml文件,把相应env的配置以hash存入全局变量。以后以此全局变量来取得配置值。
3.2 系统配置。rails3的系统配置大部分都在config/application.rb中。
3.2.1 config.autoload_paths里要加上#{config.root}/lib,3.0版本里不再自动加载lib/目录。
3.2.2 数据库存储时间的字段默认使用UTC的时区,显示这些字段时要加time_zone显式转换。如果你的项目确认一辈子都在天朝玩,不想加上啰里啰嗦的显式转换,可如此设置:
3.2.3 诸如ckeditor这样的组件要用到i18n,为了不出问题,最好还是显式指定项目的语言:
3.2.4 日志数据太多,可设置自动轮换,每周换一个新的文件:
3.2.5 更换默认缓存和解析器:
3.2.6 扩展css和js命名:
4、相关问题
4.1 初始化顺序。功能模块和某些配置的代码,有些在config/application.rb中,有些在config/initializers目录下的.rb里,有些库在lib/下面,这就涉及到一个rails初始化顺序的问题。如果代码执行的顺序不对,就会得不到预期的效果,或者会出一些莫名其妙的问题。rails3启动时的初始化顺序大致如下:
以上顺序未做深入研究,不保证完全正确,权威指南请移步官方文档。
4.2 sendfile。如果用nginx passenger做rails应用服务器,而且使用send_file或send_data来发送比如需要先身份验证等特殊需求的文件,需要在config/environments/下面的配置文件中设置:
否则send_file送出的文件大小为0。
4.3 本地化。需要翻译输出本地化文字的时候,尽量在config/locales/下面的相应文件里定义,这样能够精简erb或model的代码,职责也分得很清楚。目前我们在locales下面放了authlogic、formtastic、model中字段中文名和rails系统信息的中文翻译。
4.4 路由。rails3的routes语法改动比较大,而且写起来很*。从项目管理的角度来说,有必要对routes的写法做统一的培训,使团队成员都真正理解routes的语法规则和适用环境,能统一使用最优写法的就尽量使用,实在不行再用其它写法解决。这样routes风格会比较统一。而作为反例,现在我们项目里的routes就是大家各显神通,什么样的写法都有,很不利于沟通和维护。
4.5 js框架。rails 3.0的默认js框架仍然是prototype,在jquery大行其道的今天,这个做法有点逆潮流而动。作为某些简单的js功能,用js generator是省时省力的做法,代码也干净。找了一个N年前就不更新的rails2的jquery rails,改了改使之适用于rails3,简单功能先凑合着用了。还好,3.1终于把默认js框架改成jquery了,当真是从善如流,幸甚至哉。
4.6 测试效率。即使在ubuntu平台上,跑rspec时rails所做的前期准备工作现在也延长到了好几秒钟,作为珍惜生命的开发人员,这几秒钟是难以忍受的。我们引入了spork作为测试的加速器,它会事先prefork出完整的测试环境,节省了初始化加载的时间。不过很不幸,我们现在做的rspec很少,所以在spork方面不做太多发言。
5、调优
在江湖的传说中,很多哥都会用“效率低下”来攻击rails。不过作为一个非计算密集型的项目,我们很少会注意到rails在代码执行上有瓶颈。但是在以下几个方面,我们还是感觉到了rails的某些不足,也尝试着做了一些优化。就效果来看,虽然没有数量级上的提升,但作为项目来说基本达到了要求。
5.1 应用初始化。rails3引入了rack作为底层架构,在架构层面上比rails2更为复杂,所以在应用的初始化时耗时相对较长。我们通过设置passenger_min_instances,提前多启动几个实例,减少用户访问时启动实例的时间。另外使用passenger_pre_start http://www.xxx.com/来初始化rails应用,减少初次访问的响应时间。不过比较郁闷的是,passenger_pre_start貌似效果并不是很明显,而且不支持touch restart.txt的重启,不知道以后会不会好一些。
5.2 虚拟机参数。即使是ree,ruby虚拟机的默认参数也基本上不满足普通应用的需求。我们参考了网上有关twitter和37signal的参数值,修改配置如下:
5.3 erb解析。rails3的erb解析效率还是比较低的,听说默认的erb解析器erubis还是用c写的,不知道是我们的服务器不够强劲还是效率本来就如此。我们网站的首页大概有1000行erb,在使用了新的虚拟机参数之后,渲染时间大约在1秒钟左右。这个时间在用户体验上属于不可接受的范围。
我们把首页中渲染耗时较长的代码独立成片段文件,每个文件里面全部使用片段缓存机制。例如:
其中$recommend_pageid是rails在初始化时计算的该片段文件的md5值,这样如果该片段文件有改动,缓存中就不存在这个新的key “recommend_xxxxxx”,rails将重新生成该片段的缓存。这个方法既可使用片段缓存提高渲染速度,又可实现片段文件改动时的缓存自动更新。
使用片段缓存之后,首页渲染时间降低到了200ms左右,基本满足了要求。当然我们还留了一部分页面代码没做缓存。作为一个懂人情讲政治的开发团队,要给自己留出足够的业绩提升空间以体现自身价值,并且给领导留出足够的命令空间以展现领导权威。这样下一次领导再让你进一步缩短首页访问时间时,双方可皆大欢喜。
6、rails on windows
首先我承认,windows确实很不适合rails开发,尤其是那个执行效率,生活在mac和ubuntu上的幸福的人儿是永远都体会不到的。不过,如果rails只是我生命中的一小部分,其它大部分事情我确实需要在windows上做,而且我还很不喜欢虚拟机,那就要研究在windows上开发rails了。本节内容仅是给喜欢windows的同学提供一点参考,ubuntu和mac控可鄙视加无视。
其实解决方案很简单,就是使用rubyinstaller,同时安装devkit。基于mingw32的这套系统应该还算不错,到目前为止,一般的需要编译的gem象mysql2、nokogiri等等都没问题,最多也就是加几个参数,便可编译安装。迄今只有SystemTimer因为使用到了linux的底层SIGALRM而无法安装,不过也可以想个办法绕过去即可,不影响实际使用。
我的操作系统是windows 7 sp1 ultimate x32,不要用x64,x64下的mysql2安装会有一些莫名其妙的问题。感觉x32位还是比x64方便,一般不会出兼容性问题。至于4G内存的限制,打个补丁就行了。
6月8号一天rails版本4连发就是fix这个问题。。
官方博客还更新了一篇文章:http://weblog.rubyonrails.org/2011/6/8/potential-xss-vulnerability-in-ruby-on-rails-applications
6月8号一天rails版本4连发就是fix这个问题。。
官方博客还更新了一篇文章:http://weblog.rubyonrails.org/2011/6/8/potential-xss-vulnerability-in-ruby-on-rails-applications
嗯,那篇文章是说为防止XSS攻击,所以才设置safe_buffer不允许修改,但是没说那个cache的bug。感觉这个bug还是比较严重的,凡是使用片段缓存的页面,肯定都要挂。比较严重的事故啊,测试不到位。
官方反应还是很快的,3.0.9rc1马上就修正了这个问题,改了actionpack里面的cache_helper.rb,没有直接output_buffer.slice!,而是先to_str了一下,然后slice!,再new成output_buffer。我也是参照官方的解决方案,直接把3.0.8的代码给改了,反正也用不了几天,估计3.0.9正式版很快就会发布。
4.5 js框架。rails 3.0的默认js框架仍然是prototype,在jquery大行其道的今天,这个做法有点逆潮流而动。作为某些简单的js功能,用js generator是省时省力的做法,代码也干净。找了一个N年前就不更新的rails2的jquery rails,改了改使之适用于rails3,简单功能先凑合着用了。还好,3.1终于把默认js框架改成jquery了,当真是从善如流,幸甚至哉。
在3.1之前如果想用jquery的话,推荐
https://github.com/rails/jquery-ujs
4.5 js框架。rails 3.0的默认js框架仍然是prototype,在jquery大行其道的今天,这个做法有点逆潮流而动。作为某些简单的js功能,用js generator是省时省力的做法,代码也干净。找了一个N年前就不更新的rails2的jquery rails,改了改使之适用于rails3,简单功能先凑合着用了。还好,3.1终于把默认js框架改成jquery了,当真是从善如流,幸甚至哉。
在3.1之前如果想用jquery的话,推荐
https://github.com/rails/jquery-ujs
我们现在用的就是ujs,不过ujs只是在表单等基础层面上替换为jquery,我说的是用jquery实现rjs,象replace_html这些简单的功能。
现在rails 3.1用的是jquery-rails,也兼容3.0。不过还是不支持rjs,官方的意思是rjs已经被踢出去了,默认不再支持。prototype和rjs被移到prototype-rails了。
jrails的作者问过jquery-rails的作者,问他们想不想加入jquery对rjs的支持,结果人家没鸟他,意思是3.1已彻底放弃rjs了。看来谁想在3.1继续用rjs又不想引入prototype,得寻求其它解决方案,或者自己搞一个jquery-rjs。
部署的会写,可参见第一篇末尾的计划。不过什么时候写就不保准了,尽快吧。
rails3项目解析之1——系统架构
rails3项目解析之3——redis
rails 3.0是2010年8月份发布的。迄今为止,3.0已历经多个tiny版到了3.0.8。3.1已经放出rc4,看起来离正式版已为期不远。相对于2系,3系还是有一些令人惊喜的变化,而且在架构上也规范和严整了许多。3.1中更是又加入了几个颇为有趣的特性。我们的项目一直都是紧跟rails新版,很欣慰能够毫无道德压力地做一个喜新厌旧常换常新的男人。但什么都追新也吃了不少小苦头,不过仍然死不悔改,大家都在坐等3.1发布试吃。
更多关于rails3的新特性,网上一抓一把,需求和欲望比较强烈的同学可自行解决,在此不再赘述。下面主要说一下我们这个项目。因为项目不大,而且第一期没有太多用户互动的内容,所以涉及到的知识范畴比较小,都是些基础的东西。
1、目录结构
除那些默认目录之外,我们在项目中又另外加了一些自定义的目录来做不同的事情。
1.1 errros/。在app/目录之下,内容是各种自定义的XxxError类。使用异常机制能够使得代码更加清晰,流程语义更准确,更好地实现模块化的程序结构。
1.2 validators/。在app/目录之下,内容是继承自ActiveModel::EachValidator的各种验证类。使用自定义验证类能够使代码更加简洁,复用性更强。如:
validates :username, :availability => true, :legality => true, :username => true, ......
这里面就使用了三个自定义验证类:可用、合法、符合用户名规则。
1.3 workers/。在app/目录之下,内容是resque任务的定义类。
1.4 其它和项目相关的目录。比如在项目根目录下,我们加了一个monitor/目录,里面是resque和redis的监控脚本。因为监控脚本在概念上属于项目外层,所以放到根目录下面,不隶属于app/。
2、使用组件
2.1 rails 3.0.8。这个没什么可说的,用蜂蜜,川贝,桔梗,加上天山雪莲配制而成,实在是居家旅行、杀人灭口之必备良药。不过我们在3.0.8上吃了点苦头,丫把safe_buffer设置为不可改动,结果页面片段缓存的cache方法中的slice!触犯了这个禁条,网站首页直接挂掉。还好,发现这个问题是晚上10点,没有造成太多损失。3.0.9已经修正了这个大bug,请各位不必多虑。
2.2 mysql2。舍弃了mysql驱动,使用mysql2。不过要设置为'< 0.3.0',0.3版的mysql2是配合rails 3.1的。
2.3 ruby-oci8、activerecord-oracle_enhanced-adapter。连接公司oracle数据库取行情数据的。还需要安装oracle的instant client,把安装目录添加到/etc/ld.so.conf.d里,然后ldconfig。有想用oracle的可做参考。
2.4 nokogiri、yajl-ruby。正好项目中也要用到nokogiri,所以就干脆替代了rails自带的xml和json解析器。
2.5 authlogic、cancan。比较了一下authlogic和devise,感觉各有利弊。因为authlogic对于namespace的处理比较灵活,而且也利于第三方身份验证的扩展,比较适合我们的需求,所以最后选了authlogic。cancan对于不是很复杂的权限验证,也差不多够用了。更细粒度的权限系统,恐怕就得根据需求自己定制了。
2.6 acts_as_list、acts_as_state_machine、will_paginate。前两个不解释。will_paginate的rails3版本已经很久没更新了,不知道作者是恋爱了还是失业了。kaminari是个很好的替代,只是有些功能还没完善,是否可以完全替换will_paginate有待论证。
2.7 ckeditor、paperclip、rmagick。其实富文本编辑器已经有不少了,比ckeditor好的也不乏其数。不过具备相配合的成熟gem的,恐怕目前还只有ckeditor。如果不嫌麻烦,可以找个更好的编辑器,直接挂上去用,或者自己写gem挂到rails上。
2.8 redis-store、SystemTimer、mongoid。使用redis作为默认的rails缓存,SystemTimer是redis client等几个gem要求使用的,ruby 1.8.7的timeout不可靠,我见到的几个gem的作者都强烈建议使用SystemTimer。mongoid支持rails3,所以就没用mongo_mapper。mongoid配置简单,语法很不错,功能比较强大。
2.9 resque、resque-scheduler、eventmachine。研究过twitter当初做的starling和workling,勉强能用,但配置很复杂,而且很久不更新了,就始乱终弃之。resque套件另行开文,在此不多说。
2.10 formtastic。formtastic号称是语义表单,实际用起来还是挺不错的,erb上的代码简洁多了,学习曲线也不高,一看即会。而且formtastic扩展性非常好,我们修正了和ckeditor的接口,还自定义了日期选择(date_picker on jquery)、日期选择组(date_selects)和验证码(captcha)控件。
2.11 client_side_validations。这年头网站上没个客户端动态验证,出门都不好意思跟人家打招呼。它能够直接使用model中定义的验证规则,DRY得很。而且能够和formtastic无缝整合。另外也很好扩展,我们利用回调加上了动态验证时的绿对号红叉号的小图片。
2.12 capistrano、capistrano-ext。代码发布管理的。如果你有不同开发环境的十几台服务器需要依次发布代码,就知道这东西有什么用处了。同样,这部分将另行开文。
3、配置
虽然说“约定优于配置”,但也不能没配置。不过如果只要配置配置就能搞定,总比写代码好多了。
3.1 自定义配置。项目中要使用到一些自定义的配置,比如oracle数据库的地址、redis服务器地址等等,而且开发环境和产品环境的还不一样。我们在config/目录下放了一个configuration.yml,里面区分出不同的environment,各个env下写入各自的配置。rails初始化的时候读取该yml文件,把相应env的配置以hash存入全局变量。以后以此全局变量来取得配置值。
3.2 系统配置。rails3的系统配置大部分都在config/application.rb中。
3.2.1 config.autoload_paths里要加上#{config.root}/lib,3.0版本里不再自动加载lib/目录。
3.2.2 数据库存储时间的字段默认使用UTC的时区,显示这些字段时要加time_zone显式转换。如果你的项目确认一辈子都在天朝玩,不想加上啰里啰嗦的显式转换,可如此设置:
config.time_zone = 'Beijing' config.active_record.default_timezone = :local
3.2.3 诸如ckeditor这样的组件要用到i18n,为了不出问题,最好还是显式指定项目的语言:
config.i18n.default_locale = 'zh-CN' I18n.default_locale = 'zh-CN'
3.2.4 日志数据太多,可设置自动轮换,每周换一个新的文件:
config.logger = Logger.new(config.paths.log.first, 'weekly')
3.2.5 更换默认缓存和解析器:
config.cache_store = :redis_store, ‘redis://xx.xx.xx.xx:6379’ ActiveSupport::XmlMini.backend = 'Nokogiri' ActiveSupport::JSON.backend = 'Yajl'
3.2.6 扩展css和js命名:
config.action_view.stylesheet_expansions[:formtastic] = %w(formtastic formtastic_changes)
4、相关问题
4.1 初始化顺序。功能模块和某些配置的代码,有些在config/application.rb中,有些在config/initializers目录下的.rb里,有些库在lib/下面,这就涉及到一个rails初始化顺序的问题。如果代码执行的顺序不对,就会得不到预期的效果,或者会出一些莫名其妙的问题。rails3启动时的初始化顺序大致如下:
config.ru -> config/environment.rb -> config/application.rb -> config/boot.rb -> rails framework -> bundle gems -> configs in config/application.rb -> alphabetical .rb files in config/initializers
以上顺序未做深入研究,不保证完全正确,权威指南请移步官方文档。
4.2 sendfile。如果用nginx passenger做rails应用服务器,而且使用send_file或send_data来发送比如需要先身份验证等特殊需求的文件,需要在config/environments/下面的配置文件中设置:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
否则send_file送出的文件大小为0。
4.3 本地化。需要翻译输出本地化文字的时候,尽量在config/locales/下面的相应文件里定义,这样能够精简erb或model的代码,职责也分得很清楚。目前我们在locales下面放了authlogic、formtastic、model中字段中文名和rails系统信息的中文翻译。
4.4 路由。rails3的routes语法改动比较大,而且写起来很*。从项目管理的角度来说,有必要对routes的写法做统一的培训,使团队成员都真正理解routes的语法规则和适用环境,能统一使用最优写法的就尽量使用,实在不行再用其它写法解决。这样routes风格会比较统一。而作为反例,现在我们项目里的routes就是大家各显神通,什么样的写法都有,很不利于沟通和维护。
4.5 js框架。rails 3.0的默认js框架仍然是prototype,在jquery大行其道的今天,这个做法有点逆潮流而动。作为某些简单的js功能,用js generator是省时省力的做法,代码也干净。找了一个N年前就不更新的rails2的jquery rails,改了改使之适用于rails3,简单功能先凑合着用了。还好,3.1终于把默认js框架改成jquery了,当真是从善如流,幸甚至哉。
4.6 测试效率。即使在ubuntu平台上,跑rspec时rails所做的前期准备工作现在也延长到了好几秒钟,作为珍惜生命的开发人员,这几秒钟是难以忍受的。我们引入了spork作为测试的加速器,它会事先prefork出完整的测试环境,节省了初始化加载的时间。不过很不幸,我们现在做的rspec很少,所以在spork方面不做太多发言。
5、调优
在江湖的传说中,很多哥都会用“效率低下”来攻击rails。不过作为一个非计算密集型的项目,我们很少会注意到rails在代码执行上有瓶颈。但是在以下几个方面,我们还是感觉到了rails的某些不足,也尝试着做了一些优化。就效果来看,虽然没有数量级上的提升,但作为项目来说基本达到了要求。
5.1 应用初始化。rails3引入了rack作为底层架构,在架构层面上比rails2更为复杂,所以在应用的初始化时耗时相对较长。我们通过设置passenger_min_instances,提前多启动几个实例,减少用户访问时启动实例的时间。另外使用passenger_pre_start http://www.xxx.com/来初始化rails应用,减少初次访问的响应时间。不过比较郁闷的是,passenger_pre_start貌似效果并不是很明显,而且不支持touch restart.txt的重启,不知道以后会不会好一些。
5.2 虚拟机参数。即使是ree,ruby虚拟机的默认参数也基本上不满足普通应用的需求。我们参考了网上有关twitter和37signal的参数值,修改配置如下:
RUBY_HEAP_MIN_SLOTS=500000 RUBY_HEAP_SLOTS_INCREMENT=250000 RUBY_HEAP_SLOTS_GROWTH_FACTOR=1 RUBY_GC_MALLOC_LIMIT=50000000 RUBY_HEAP_FREE_MIN=100000
5.3 erb解析。rails3的erb解析效率还是比较低的,听说默认的erb解析器erubis还是用c写的,不知道是我们的服务器不够强劲还是效率本来就如此。我们网站的首页大概有1000行erb,在使用了新的虚拟机参数之后,渲染时间大约在1秒钟左右。这个时间在用户体验上属于不可接受的范围。
我们把首页中渲染耗时较长的代码独立成片段文件,每个文件里面全部使用片段缓存机制。例如:
<% cache "recommend_#{$recommend_pageid}" do %> …… <% end %>
其中$recommend_pageid是rails在初始化时计算的该片段文件的md5值,这样如果该片段文件有改动,缓存中就不存在这个新的key “recommend_xxxxxx”,rails将重新生成该片段的缓存。这个方法既可使用片段缓存提高渲染速度,又可实现片段文件改动时的缓存自动更新。
使用片段缓存之后,首页渲染时间降低到了200ms左右,基本满足了要求。当然我们还留了一部分页面代码没做缓存。作为一个懂人情讲政治的开发团队,要给自己留出足够的业绩提升空间以体现自身价值,并且给领导留出足够的命令空间以展现领导权威。这样下一次领导再让你进一步缩短首页访问时间时,双方可皆大欢喜。
6、rails on windows
首先我承认,windows确实很不适合rails开发,尤其是那个执行效率,生活在mac和ubuntu上的幸福的人儿是永远都体会不到的。不过,如果rails只是我生命中的一小部分,其它大部分事情我确实需要在windows上做,而且我还很不喜欢虚拟机,那就要研究在windows上开发rails了。本节内容仅是给喜欢windows的同学提供一点参考,ubuntu和mac控可鄙视加无视。
其实解决方案很简单,就是使用rubyinstaller,同时安装devkit。基于mingw32的这套系统应该还算不错,到目前为止,一般的需要编译的gem象mysql2、nokogiri等等都没问题,最多也就是加几个参数,便可编译安装。迄今只有SystemTimer因为使用到了linux的底层SIGALRM而无法安装,不过也可以想个办法绕过去即可,不影响实际使用。
我的操作系统是windows 7 sp1 ultimate x32,不要用x64,x64下的mysql2安装会有一些莫名其妙的问题。感觉x32位还是比x64方便,一般不会出兼容性问题。至于4G内存的限制,打个补丁就行了。
1 楼
yang_kunlun
2011-06-10
畅快啊, 楼主功力深厚啊
2 楼
xinghu
2011-06-10
如沐春风~~
大牛你好 !
大牛你好 !
3 楼
bluebu
2011-06-10
希望rails3.1中的erb解析效率能够提高些。。。
4 楼
wowpzp
2011-06-10
学习了!感谢楼主!
5 楼
Hooopo
2011-06-10
引用
不过我们在3.0.8上吃了点苦头,丫把safe_buffer设置为不可改动,结果页面片段缓存的cache方法中的slice!触犯了这个禁条,网站首页直接挂掉。还好,发现这个问题是晚上10点,没有造成太多损失。3.0.9已经修正了这个大bug,请各位不必多虑。
6月8号一天rails版本4连发就是fix这个问题。。
引用
Rails 3.0.9.rc1 has been released!
Rails 2.3.12 has been released!
Rails 3.0.8 has been released!
Rails 3.1.0.rc2 has been released!
Rails 2.3.12 has been released!
Rails 3.0.8 has been released!
Rails 3.1.0.rc2 has been released!
官方博客还更新了一篇文章:http://weblog.rubyonrails.org/2011/6/8/potential-xss-vulnerability-in-ruby-on-rails-applications
6 楼
seamon
2011-06-10
Hooopo 写道
引用
不过我们在3.0.8上吃了点苦头,丫把safe_buffer设置为不可改动,结果页面片段缓存的cache方法中的slice!触犯了这个禁条,网站首页直接挂掉。还好,发现这个问题是晚上10点,没有造成太多损失。3.0.9已经修正了这个大bug,请各位不必多虑。
6月8号一天rails版本4连发就是fix这个问题。。
引用
Rails 3.0.9.rc1 has been released!
Rails 2.3.12 has been released!
Rails 3.0.8 has been released!
Rails 3.1.0.rc2 has been released!
Rails 2.3.12 has been released!
Rails 3.0.8 has been released!
Rails 3.1.0.rc2 has been released!
官方博客还更新了一篇文章:http://weblog.rubyonrails.org/2011/6/8/potential-xss-vulnerability-in-ruby-on-rails-applications
嗯,那篇文章是说为防止XSS攻击,所以才设置safe_buffer不允许修改,但是没说那个cache的bug。感觉这个bug还是比较严重的,凡是使用片段缓存的页面,肯定都要挂。比较严重的事故啊,测试不到位。
官方反应还是很快的,3.0.9rc1马上就修正了这个问题,改了actionpack里面的cache_helper.rb,没有直接output_buffer.slice!,而是先to_str了一下,然后slice!,再new成output_buffer。我也是参照官方的解决方案,直接把3.0.8的代码给改了,反正也用不了几天,估计3.0.9正式版很快就会发布。
7 楼
活靶子
2011-06-11
感谢~感谢~
8 楼
QuakeWang
2011-06-11
引用
4.5 js框架。rails 3.0的默认js框架仍然是prototype,在jquery大行其道的今天,这个做法有点逆潮流而动。作为某些简单的js功能,用js generator是省时省力的做法,代码也干净。找了一个N年前就不更新的rails2的jquery rails,改了改使之适用于rails3,简单功能先凑合着用了。还好,3.1终于把默认js框架改成jquery了,当真是从善如流,幸甚至哉。
在3.1之前如果想用jquery的话,推荐
https://github.com/rails/jquery-ujs
9 楼
agile_boy
2011-06-12
受教了,谢谢分享。
10 楼
jn615
2011-06-12
学习了, 不错的东东
11 楼
edokeh
2011-06-13
第一次听说client_side_validations,之前我看到最好的前端验证框架是jquery validate,不知道client_side_validations的功能与定制性究竟如何,但是能与后端公用一套校验规则,还是很吸引人的
12 楼
seamon
2011-06-14
QuakeWang 写道
引用
4.5 js框架。rails 3.0的默认js框架仍然是prototype,在jquery大行其道的今天,这个做法有点逆潮流而动。作为某些简单的js功能,用js generator是省时省力的做法,代码也干净。找了一个N年前就不更新的rails2的jquery rails,改了改使之适用于rails3,简单功能先凑合着用了。还好,3.1终于把默认js框架改成jquery了,当真是从善如流,幸甚至哉。
在3.1之前如果想用jquery的话,推荐
https://github.com/rails/jquery-ujs
我们现在用的就是ujs,不过ujs只是在表单等基础层面上替换为jquery,我说的是用jquery实现rjs,象replace_html这些简单的功能。
现在rails 3.1用的是jquery-rails,也兼容3.0。不过还是不支持rjs,官方的意思是rjs已经被踢出去了,默认不再支持。prototype和rjs被移到prototype-rails了。
jrails的作者问过jquery-rails的作者,问他们想不想加入jquery对rjs的支持,结果人家没鸟他,意思是3.1已彻底放弃rjs了。看来谁想在3.1继续用rjs又不想引入prototype,得寻求其它解决方案,或者自己搞一个jquery-rjs。
13 楼
richyzhang
2011-06-14
rjs已经被抛弃了。rails3.0的时候已经很明显了。对新手来说,rjs还是很棒的,可以一点不懂js照样写出dhtml和ajax的应用。然而,随着越来越多的js高手的出现,rails团队自身对js的熟练,现在提倡直接写js。不过js虽然很强大,却难看了点,于是又搞出了coffeescript。
你说的replace_html基本上现在可以这么写
<%=link_to “say hello”, { :controller => “welcome”, :action => “say” }, :id => “ajax-load”, :remote => true, “data-type” => “html”%>
:id指明了要replace的内容,date-type说明返回的是一个html,:remote表示是一个ajax调用。
你说的replace_html基本上现在可以这么写
<%=link_to “say hello”, { :controller => “welcome”, :action => “say” }, :id => “ajax-load”, :remote => true, “data-type” => “html”%>
:id指明了要replace的内容,date-type说明返回的是一个html,:remote表示是一个ajax调用。
14 楼
edokeh
2011-06-20
想知道LZ是如何部署的,不知道能不能再写一篇文章
15 楼
seamon
2011-06-27
edokeh 写道
想知道LZ是如何部署的,不知道能不能再写一篇文章
部署的会写,可参见第一篇末尾的计划。不过什么时候写就不保准了,尽快吧。
16 楼
keer2345
2011-06-30
rubyinstaller.org 是不是被墙了?打开不了页面,唉
17 楼
wowpzp
2011-06-30
请问楼主acts_as_list、acts_as_state_machine 应用在什么场合呢?有什么优点呢?谢谢!