Welcome

首页 / 软件开发 / 数据结构与算法 / Rails系统重构:从单一复杂系统到多个小应用集群

Rails系统重构:从单一复杂系统到多个小应用集群2010-10-28 infoq 郭磊Ruby on Rails近几年在国内受到越来越多的开发者的青睐,Rails应用也从较简单的内部系统深入到复杂的企业级应用。Rails“习惯优于配置”的思想以及ActiveRecord等众多优秀的技术极大地提高了开发效率,但在业务复杂的大型系统中,Rails应用也会面临很多问题。

本文将介绍一种Rails系统重构方案,将复杂的Rails单一系统拆分成相互协作的多个轻量级应用集群,从根本上解决Rails系统在处理复杂的业务时代码臃肿、开发效率降低、难以维护与部署等问题。

复杂Rails系统存在的问题

用Rails可以快速搭建一个较简单的应用,但当业务需求急剧增长,功能越来越复杂时,系统的维护和扩展会变得越来越困难。一般情况下,问题主要表现在以下几个方面:

代码臃肿

我们知道Rails提倡RESTful架构,所以良好的代码组织方式是对每一个实体(Model)都有相应的处理器(Controller)来进行操作,而Rails每个Controller都有一个相应的Helper以及若干个View。这样当系统功能比较复杂时,代码量会急剧增大。

首先是Model的数量会很多。由于Model都放在app/models目录下面,而Rails又不支持Model分目录,虽然可以通过修改 load_paths解决这一问题,但有时(如目录与Model重名)会造成难以调试的错误,所以当Model数量比较多时,这个目录会变得难以管理。

其次是Controller的目录层级会比较深。为保持清晰的代码结构,Controller应该按照功能分类存放在不同的目录下。所以当功能比较多时,很容易出现四五层甚至更深的目录结构,这不仅使代码难以管理,routes的配置和解析也变得很复杂,例如会出现 level1_level2_level3_level4_controller_name_path这样很长的routes Helper方法。

难以测试与部署

复杂的业务代码不仅会增加写测试代码的难度,运行测试的时间也必然会随之增加。大量的fixtures不仅难以管理,还经常会造成互相干扰。

复杂的系统也增加了部署的风险,一个小错误可能会导致整个系统的崩溃。为了降低这种风险,需要延长系统部署的周期,只在特定的时间或系统有重大更新时才部署,这样就在一定程度上弱化了Rails系统根据用户需求快速升级迭代的优点。

影响团队建设

除了技术上的问题,复杂的Rails系统对团队建设也会产生不利影响。首先如果某个开发人员提交了测试无法通过的代码,会对其他人的工作产生影响,降低开发效率;其次对于复杂的系统,增加新功能或修复bug都变得比较困难,久而久之程序员就会产生惰性,代码能少改的就少改,严重阻碍了系统的快速进化;最后在团队有新人加入时,会担心由于其不熟悉系统造成系统崩溃,而不敢放手让他真正参与进来,这样对新人的成长是十分不利的。

轻量级应用集群

为解决复杂的Rails系统产生的一系列问题,我们将单一系统按照业务功能进行划分,每一部分用一个独立的Rails应用来实现,从而形成若干个轻量Rails应用集群,这些应用相互协作,共同实现整体业务逻辑。

拆分后每一个Rails应用具有如下特征:

有独立的数据库,可以独立运行;

程序代码量比较小,一般情况下只需要一到两个程序员开发与维护;

高内聚、低耦合。

系统进行拆分后,需要解决一系列关键的问题,例如:如何保持用户体验的一致性、应用之间如何交互、如何共享用户等。下面将逐一针对这些问题介绍解决方案。

用户体验一致性

系统进行拆分后,由若干个轻量级应用共同协作来完成某项业务操作。由于每一个应用都是独立的Rails程序,而一个较为复杂的业务流程可能要在多个应用间跳转,所以首先要解决用户体验的一致性问题。

统一的css框架

用户体验最直观的方面就是页面的样式。为了保证用户在不同的程序间跳转时没有突兀的感觉,每个应用看起来都应该“长的一样”。为达到这一目的,我们采用统一的css框架来控制样式。

在layout里面调用Helper方法:

<%= idp_include_js_css %>

这将产生以下html代码:

<script src ="/assets/javascripts/frame.js" type="text/javascript"></script>
<link href="/assets/stylesheets/frame.css" media="screen" rel="stylesheet" type="text/css" />

在frame.css中,会设定好html标签以及如导航等常用结构的样式,应用中的页面只要使用定义好的标签及css类,就可以实现统一风格的界面。