`

Rails应用优化指南(1)

阅读更多
Rails应用优化指南

  如果你是一名Rails开发者,那么随着你的项目变得越来越庞大,你是否觉得你的Rails应用的响应速度变得越来越缓慢呢?来自Stefan Kaes的这篇关于Rails应用性能优化的文章或许能够帮你摆脱困境,虽说年代有些久远(RailsCONF 06上的一篇演讲稿[1]),但是其中的一些思想以及实践方法还是值得我们学习的。

  首先,在开始优化你的应用之前,我们需要先明确以下几点:

没有相应的测试用例作为基础,就开始盲目的优化是非常愚蠢的;
如果你的应用是因为设计不合理而导致性能低下,那么我建议你最好花点时间重构你的代码,而不是进行局部的优化,因为这只会使问题越来越多;
在优化之前,最好先为自己树立一个目标,这样可以防止因为过度优化而浪费时间,达到预先设定的目标后就应该停下来了;
没有必要对每一个页面都进行优化,只需要关注那些最经常被访问的页面就可以了;
在开发期间,进行持续的性能测量,这样有助于你在优化时定位性能瓶颈。
  其次,一旦优化完成,我们需要确定一组性能参数来衡量我们的优化效果,常用的参数包括以下这几个:

延迟,即响应一个请求需要多少时间;
吞吐量,即每秒最多可以处理多少个请求;
系统利用率,在大量请求需要处理的时候,你的系统在满负荷运转吗?(比如CPU占用率达到100%了吗);
资源开销,在每个请求上所花费的资源开销。
  确定了要测量的性能参数,我们还需要一个自动化的基准(benchmark)测试工具来帮我们完成应用性能的测量,以及对多次测量的结果进行比对,我们可以通过以下工具来获得应用的各项性能指标:

Rails日志文件(debug_level >= Logger::DEBUG);
Rails日志分析工具(需要将日志输出到syslog)(RailsLogVisualizer就是一款不错的Rails日志分析工具;
Rails自带的基准测试脚本(script/benchmarker);
数据库提供的性能分析器;
Apache Bench(ab或者ab2);
httperf;
railsbench。
  我推荐Railsbench,不同于其他工具,它测量的是Rails应用的原生性能(Raw performance)。由于去除了网络延迟等中间因素的干扰,Railsbench让你可以将精力集中到Rails应用本身,从而让你的优化变得更有针对性且高效(译者注:关于Railsbench的使用参看[3])。

  除了基准测试工具外,你也可以选择单纯的性能测试工具:

Ruby profiler;
Zen profiler;
rubyprof;
Rails profiler script;
Ruby Performance Validator(商业软件,仅支持windows)。
  不过事实上,Railsbench已经内置了性能测试工具,所以单独使用这些工具的必要性不大。

  介绍完工具,下面就正式开始我们的优化之旅吧!

  根据我的经验,Rails应用的性能问题一般集中在以下几个方面:

很慢的helper方法;
复杂的路由;
过多的联合(associations);
过多的数据库访问;
缓慢的session存取。
  不过,数据库的性能基本可以不用考虑,因为相比于构造ActiveRecord对象的开销,连接数据库本身的开销几乎可以忽略不计。

  在真正开始之前,还是有一点需要提前说明,优化策略事实上大部分情况下都不具备通用性,因为软硬件差异,用户使用习惯等等原因,可能会造成同一条优化策略在不同系统中得到完全不同的效果。不过也不必担心,这篇文章里讲的都是一些具有普遍适用性的策略。尽管如此,我还是建议你在应用这些策略时进行一下对比测试,因为很有可能它们对你的系统的作用有限,或者干脆不起作用,就像我们在开头说的,不要盲目优化。

  优化Session

  如果你的系统需要为每个访问者保存单独的Session信息(比如购物网站),那么session的存取速度将是影响系统性能的关键因素,目前可用的session存取策略有:

内存,快,相当快!但是如果你的应用挂了,或者由于其它什么原因需要重启,那么所有的session信息都会丢失,并且这种方式仅仅只能在单APP Server的应用中使用;
文件系统,很容易使用,每个session对应一个文件,并且可以通过NFS或者NAS轻松进行容量扩展,但是速度较慢;
数据库/ActiveRecordStore,使用简单(Rails的默认策略),但是很慢;
数据库/SQLSessionStore,与上面一种方式类似,但是使用原始SQL取代了ActiveRecord,性能有一定提升,关于SQLSessionStore与ActiveRecordStore的对比可以参看[1];
memcached,比SQLSessionStore稍微快一些,可扩展性较好,但是较难获取统计信息,关于memcached与SQLSessionStore的对比,参看[1];
DrbStore,在memcached不支持的一些平台上,可以选择DrbStore,但是性能比memcached要差一些,并且不支持session自动清除。
  优化Cache

  Rails默认支持以下几种Cache方式:

Pages,很快,整个页面都被保存在文件系统,Web Server可以直接绕过APP Server完成请求应答,但是存在一些固有缺陷,比如无法应付需要用户登录的应用;
Actions,访问速度仅次于Pages,缓存controller的action执行结果,同时由于可以调用到controller的过滤器,因此可以很好的防止未授权用户访问;
Fragment,缓存请求结果的一部分,也可以感知用户是否登录。
  Action Cache事实上是Fragment Cache的一种特殊情况,跟session一样cache也有以下集中存取策略可供选择:

内存,最快的方式,如果你的程序只需要在一个APP Server上运行,那么这无疑是最好的方式;
文件系统,一般快,但可以使用正则表达式来刷新过期页面;
DrbStore,同文件系统相比,刷新过期页面更为快一些;
memcached,比DrbStore更快且易于扩展,但不支持使用正则刷新过期页面。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics