多子系统集成项目的总结
这次做的项目,涉及到6个子系统的集成,其中有2个是遗留系统,4个是新开发的系统。我负责其中一个新系统
前期还是比较顺利,提前完成了开发计划,并进行了比较充分的代码检视、单元测试和内部测试。但是在进入接口联调和系统集成以后,就变得非常痛苦,这2周平均每天工作时间超过16个小时。但是整个系统还是没有稳定下来,还是有非常多的问题,而且每天的效率非常低,大部分的时间都是花在等待中
为什么这次在开发这么顺利的情况下,在项目后期却会陷入这么糟糕的局面?怎么样才可能比较顺利地完成一个较大的系统?我从项目启动的第一个环节开始,对每个过程进行反思
1、做好需求
现状:我认为这次的需求做得不到位。一方面猜想了比较多的需求,与客户却没有充分地沟通过,这就造成工作量的浪费。更糟糕的是为了满足太多的需求,也影响了系统的架构,造成系统架构的臃肿,这个在后面会详细说明。另一方面,或许有一些客户真正关注的需求,我们却没有实现,这个可能会给后期系统的推广造成困难。
原因分析:会出现上述的2方面问题,我觉得本质的原因就是和客户的沟通太少。需求基本都是凭空猜想,或者根据部门内业务专家的经验推断。虽然业务专家确实有比较高的业务水平,但是毕竟不能完全代表真正客户的想法。所以与客户的沟通太少,也没有积极地邀请客户参与到系统的每一轮阶段性展示活动中。这使得我们系统的需求做得比较糟糕。
总结:应该采用敏捷开发的方式,在尽量小的迭代周期内拿出系统的小版本给客户演示,按照先核心需求,再逐步丰满的方式,不断地调整需求。与客户充分沟通,既保证满足核心需求,又避免工作量的浪费
2、宁可没有架构师,也不要找一个扯淡的
现状:或许大公司都会有这样那样的政治因素,这次项目的所谓“架构师”就是一个大忽悠。
这个系统,估算是200左右的并发规模,可以认为相当于不存在并发问题;然后数据量的规模也不大。如果简单处理的话,可以是一个逻辑架构和物理架构都非常清晰明了的系统。我个人认为,就一个应用服务器+一个数据库服务器,就绰绰有余了。即使以后数据库压力大了,再上数据库集群不就行了。毕竟这是一个业务系统,不是一个互联网应用,根本就不存在并发和海量数据的问题。这样简单处理,我认为是合适的
但是这个“架构师”,整上的东西就很多了:
要先上2个数据库,一个存放业务数据,一个存放资源数据。这样2个数据库就要同步来同步去。这周另外1个小组,就为了这个同步的问题熬了一周的通宵
子系统之间要走所谓“服务框架”,其实就是对CXF的一个封装,没任何意义,纯粹引入复杂性。其实每个子系统开放一个Servlet都可以了。这个服务框架带来的问题,伴随6个子系统整个开发流程,开发时间至少增加1/4,没带来任何价值
然后来个日志框架,其实花半小时自定义一个Appender的扩展就可以解决问题
业务可能有变化的地方,整个OSGi。不好意思,开发已经延期2周了,现在大家都还没做出来。我说真有新功能,再发布一个升级的PATCH不行?何况这个系统就没热部署的需求,业务也很稳定,强行上个OSGi,这不是有病?
本来还要上分布式,幸好大领导终于意识到风险太大,制止了。。
关键是这位“架构师”,提出了上述种种方案之后,人没了?你找他谈实现,他就给你说原则。如是再三之后,我得出一个准确判断,这些方案,他自己就听说过名词。是干什么的?知道一点。怎么实现?不好意思
总结:架构要保持简单,一个数据库能解决的问题,就不要弄多个数据源同步。不准备开放给外系统调用的接口,就不要上web service。什么扯淡的分布式,OSGi,我就不评论了。当然我不是说这些技术不好,其实我对这些技术也非常感兴趣,但是毕竟是做系统,不是在玩过家家。用在合适的地方的技术,解决实际问题带来价值的技术,才是好技术。过度架构,就是200个兄弟的累死累活,就是系统的延期,就是项目跑不起来
3、其实做好上面的2项:分析清楚需求,不瞎做。保持适当架构,不折腾。一个系统到后期就不会像这次这么痛苦了,我认为上述2项是最重要的。后面的都是比较细节的问题
4、越早对齐数据库越好
服务端有2个数据库(Oracle),终端有1个数据库(SQLite),所以存在数据库字段不统一的问题。前期我们自己跑服务桩,啥问题没有,到了集成的时候,各种数据库字段对不齐,有的是类型不匹配,有的是长度限制不匹配,有的是非空约束不匹配,等等。大家都知道,到应用稳定以后,再去改数据库模型是相当痛苦的,因为从数据库字段,到模型对象,到DAO,都要改,不仅开发有工作量,测试也有工作量,越到后期,这个代价越大,所以应该尽早地对齐数据库
这个责任在我,是我系统集成经验不足造成的。这个教训我记住了
5、仅仅在文档层面对齐接口没用,对于涉及到多个子系统集成的项目,可以“接口驱动开发”
前期所有6个子系统,都是自己玩自己的。单元测试都不可谓不充分。也都模拟了实际场景,终端为了模拟测试业务场景,我还亲自写了一个完整的服务端桩。但是即使这样,到了集成的阶段,系统还是各种跑不起来。
其实前期领导就很重视对齐接口,每个子系统的负责人,花了一个星期来写接口文档,各子系统互相评审,并签字确认。到头来,没有用。因为实际运行的不是文档,是代码。文档虽然已经描述清楚了交互协议,每个字段也都对过了。但是接口太多,有的接口也相当复杂,在没有实际测试的情况下,谁也不能保证100%是按照文档来操作的,何况文档也不能保证是100%正确的,毕竟在开发过程中,变更是绝对会发生的,但是未必文档就能及时刷新并知会对方系统。
所以这种涉及到多个子系统集成的项目,我强烈认为应该以接口来驱动开发。每个子系统,首先实现接口。当然在开发早期,每个子系统内部的业务逻辑肯定没实现,不可能有真实业务数据,但是这种时候,可以先传递符合格式的假数据,照样可以让接口跑起来。这样到系统集成阶段,就节省了非常多的工作量。我敢保证效果绝对比这次好。
6、早点集成,不能拖到最后一起集成
这条其实和上一条强相关。这次项目基本做到了每天SVN上的代码是可运行的小迭代。但是都是每个子系统自己玩自己的。应该缩短集成的周期
当然由于每个子系统的开发进度不同,很难做到像单个子系统内部一样每日集成(我怀疑是根本不可能)。但是至少也应该可以做到半个星期或者一周集成一次。把集成的工作放到前面,可以更早的暴露问题,更早的调整。效果一定也比这次强
以上是本次项目过程中个人的一点总结。此外在代码层面,也有一些心得。包括Android应用的分发模式,Android应用的简单ORM框架,Android日志规范,接口设计,Android服务管理等。待系统集成完之后,再总结一下