--------------------------------------------------------------------------------
对于一个好的软件来说,技术选型无疑是最重要的一步,这将决定软件是否有良好的扩展性、健壮性、可靠性以及可维护性。对于DST来说,传统的B/S是一个显而易见的架构性选择,那么从前端到后端都需要有良好的Framework以及清晰的技术轨道与之配合。
在整个DST的开发周期中,围绕技术选型,曾经发生过几次重要的争论,列举如下:
1、框架之争
DST之前有Kelude测试平台可以借鉴,Kelude采用Ruby语言的Rails框架,其特点是轻巧灵活,代码极少重复,开发效率极高。然而考虑到精通Ruby语言的程序员不多,后端服务的技术人员大多精通Java而非Ruby,且海量数据平台的大部分产品都是Java开发(如Hadoop),将来在DST与测试场景接合的时候,相同的语言可以省却很多麻烦。最终定选的Webx作为一个成熟的MVC设计模式,在淘宝的使用很广泛,有大量资料实例可以参考。
持久层采用Hibernate还是ibatis,这要归功于我们团队的leader叶渡的技术选型,在后来的开发过程中,不谈外部的一般说法,我的感觉是ibatis结构非常清晰,sql语句完全被抽象到了sqlmap文件中,适合DBA以及其他开发人员对sql语句的审核。从DAO接口到之上的事务层,都可以通过ibatis很好的管理起来。但是ibatis从生成到增删改非常繁琐,增加一条sql语句,一般情况下至少要修改6、7个文件,这个过程很容易出错。
2、UI设计之争
作为后端测试工程师,因为我在DST立项开始的时候并没有太多的前端开发经验,因此在UI设计上,曾经发生过是否要专业UED参与的争论。这个争论虽然之后随着DST的开发渐渐消失,但此时提及,是为了记录我在设计过程中的一些思考。
我觉得DST如果有专业的UED协助进行用户体验的设计那是最好不过的事情,但是对于此类项目的开发早期,很多功能点不是很清晰的情况下,由开发人员掌握住整个流程还是相当有必要的。开发者的亲身参与会省去许多探雷的过程,且测试人员自己才最清楚需要一个什么样的系统,UED的参与更多从普通用户角度思考,而测试框架作为一款特殊的软件产品,更需要从开发者角度去思考他们的操作习惯。
3、海量数据持久化之争
身处海量数据开发项目,自然少不了和动辄上千个节点的集群打交道,从这些集群收集到的监控数据和日志数据的量也可以用浩如烟海来形容。按常规经验,一个百台规模的集群,收集到的监控数据一年约有8TB,传统关系型数据库撑住这样的数据量还要保持高效的并发读写效率,往往需要一个很有经验的团队来支撑,分表操作会成为一个常态。而我们所需的查询动作往往又非常简单,基本上都是扫描一段时间内的数据。这恰好是nosql型数据库最擅长的领域。
但是在这部分设计之初,我们发生了关于持久化是通过直接存取二进制文件方式,还是存取HBase方式之争。
直接存取二进制文件方式的理由是,可以直接从RRD(Round Robin Database)数据库文件中读取所需的监控数据,对查询请求可以通过固定算法计算出数据所在位置后,用seek函数直接跳转过去进行连续读取,好处是速度快,硬件资源需求少。但这样的方式带来的问题,一是查询依赖于编程,不利于查询方式的扩展和数据挖掘;二是没有足够可靠的数据冗余备份方案,一旦机器损坏,数据就将发生不可逆转的丢失;三是扩展性不够,能够hold住百级别节点的集群,并不意味着我们仅仅只有百台机器需要存取监控和日志数据,一旦规模扩大,这样的解决方案将面临无法动态扩容的危险。
最终我们选择了将监控和日志数据存到HBase中这个方案,上述的三个问题都不会发生。而在后来的设计中,我进一步发现与其从gmond保存的RRD数据库文件中读取监控数据,不如通过替代gmond master节点的方式来直接解析xml形式的监控数据。这样可以避免磁盘操作这个性能瓶颈,数据流完全是从内存到网络(gmond)再到内存(我们的工具)再通过网络到HBase集群的内存中。整个过程完全将没有磁盘这种慢速设备的干扰。关于这部分的详细设计思想,我将会在后文中继续描述。
4、敏捷开发模式实施之争
采用敏捷开发模式是DST设计过程中不可忽视的一个重要技术选型。按照书本上的定义:敏捷开发强调程序员团队与业务专家之间的紧密协作、面对面的沟通(认为比书面的文档更有效)、频繁交付新的软件版本、紧凑而自我组织型的团队、能够很好地适应需求变化的代码编写和团队组织方法,也更注重做为软件开发中人的作用。
而DST在开发之初,有过一些并不是很适宜的对某些开发点的反复关注和修改,浪费了一些时间。这在随后持续进行的迭代开发周期中,还是需要警醒自身,并持续改善的。一方面避免代码浪费,另一方面还要和业务需求层面多进行沟通,以便做出的产品与实际需求之间偏差较小。
综上所述,技术选型的过程并非是一帆风顺的,其过程尤其是人与人之间交互中,需要各方不断的争执和妥协。有些选型也并非一成不变,在发现问题之后,及时的回滚就可以了,最重要的是不可一条错路走到黑。而我们平时更愿意只选择自己最熟的路走,这对于开发产品来说并不是一件好事。
我认为一个比较好的习惯是,无论遇到什么问题,哪怕是自己已有成熟想法的,都应该首先去搜索一下业界同类问题的解决办法,能够走大部分人共同走过的路,才是最安全可靠的。我们设计一个优秀的软件,做一个零散部件的组装者要比做一个从矿工开始的开发者需要付出的更少,且有更多的机会获得成功。技术选型正是一个选择零件的过程,这比架构的角色更为重要,无论拥有多么优秀的架构,一个足够分量的错误的零件都有可能会毁掉你设计的整座大厦。