3.1 淘宝平台“服务化”历程
2007年,淘宝已经拥有超过500人的技术团队规模,整个淘宝网站是一个几百兆字节的WAR包,大小功能模块超过200个,在当时淘宝业务计划处于每隔几个月就翻倍的高速发展期,这样的应用架构给淘宝技术团队带来了非常大的压力。几百人维护一个WAR包的模式,带来了以下几个主要问题:
1)项目团队间协同成本高,业务响应越来越慢。一个超过200个功能模块的系统,必然会按照不同团队负责不同功能模块的方式进行开发。每一次系统的功能升级,一定是各个团队为各自负责的项目模块创建出新的代码分支,一旦临近新版本的系统上线时间,则会进行分支的合并。做过开发的都会知道,在这个合并的过程中,会出现各种jar包冲突、代码不一致的情况,这就需要在不同团队间进行各种确认和协调的工作。如果再遇上有些功能开发的进度滞后,让情况就变得更加复杂,最终导致每一次的版本发布都会有不少时间花费在这样的协同工作上,在耽搁系统上线时间的同时,也带来不小的协同成本。
2)应用复杂度已超出人的认知负载。淘宝从最初2003年时功能简单的C2C平台发展到2007年时,不管是功能的数量和业务流程的复杂度都非常高,淘宝早期还有同事能对平台各个功能和实现了如指掌,但面对越来越复杂的淘宝平台,各种业务错综复杂地揉在了一起(如图3-1所示的情形),已经没有一个人能完全清楚每一个功能和业务流程的细节,因为人的认知负载毕竟是有限的。这就造成每一次淘宝平台整体打包发布时,其中蕴含着非常大的风险,一个小小的功能改动可能会给其他功能带来未知的风险,整个平台给人一种“牵一发而动全身”的感觉。
图3-1 淘宝平台越来越错综复杂的系统样貌
3)错误难于隔离。淘宝平台WAR包中的200多个功能模块中有非常核心的模块,如用户、商品、交易、店铺等,这一类的功能模块相对业务比较稳定,功能迭代和更新的频率没有那么高。还有一类如广告展示、前端界面交互等非核心的功能模块,基于运营的需要,可能每天都会有新版本发布。在淘宝的历史中发生过几起事故,是因为一些非核心功能的设计不合理、代码质量差引起整个淘宝平台的业务受到全面影响,其根本原因就是核心功能和非核心功能的代码都运行在同一个环境(同一个JVM)中,任何一个小的问题都有可能造成应用实例的崩溃,从而影响到整个淘宝平台的正常运行。
4)数据库连接能力很难扩展。整个淘宝平台的所有业务功能均在一个WAR应用中,所有的数据也均保存在同一数据库集群中,而数据库集群的数据库连接数量是有上限的,这就造成数据库连接数量的资源随着淘宝应用实例数量的增加而越来越捉襟见肘,如图3-2所示。2007年,淘宝在应用代码方面做了足够好的优化,每个应用实例的连接池大小压缩到10个的情况下,峰值时间数据库的连接数量已经超过5000个,离数据库官方支持的连接数上限已经非常接近,平台也已经因为过高的数据库连接处于一个非常不稳定的状态。
图3-2 数据库连接数已经达到上限
5)应用扩展成本高。一个包含几百个功能的WAR包所需要的初始和运行资源就不会太小,使得我们需要采用较高资源配置的服务器支撑应用实例的运行。更重要的是,我们发现系统在出现业务处理瓶颈的时候,只是由于某一个或几个功能模块(比如在大促时商品库存功能和订单创建功能的压力会非常大)负载较高造成的,但因为所有功能都打包在一起,所以在出现此类性能问题并且需要通过增加应用实例的方式分担服务负载时,则没法对单独的几个功能模块进行服务能力的扩展,而只能将整个完整的应用进行扩容,带来了资源额外配置的消耗,成本较高。
以上几个问题,一部分是成本问题;一部分是对于淘宝高速发展的业务是否能够做到快速、稳定的支持;还有一部分问题则是直接决定了技术平台是否还能支撑淘宝平台继续发展下去的关键问题。也就是说,如果继续沿袭现在的架构发展,将很快遇到平台发展的瓶颈,从而无法再对淘宝业务的发展带来有效的支持。所有人都意识到了这个问题,所以淘宝从2007年开始整个技术体系架构坚持走自主可控、创新变革之路,这点很多人是知道的。
解决以上问题的根本就在于业务的拆分,而当时业界已经盛行的SOA理念和方法则是有效解决以上问题的不二选择。我个人是SOA理念的坚定拥护者,因为看到了太多基于SOA建设或重构的系统给企业带来了实实在在的业务能力和竞争力的提升。所以淘宝在2007年10月开始了一系列的基于SOA理念新一代服务化框架研发以及采用业务模块逐步迁移的方式进行应用架构的改造工作。
首先淘宝从现有应用中选择了用户相关的功能作为试点,剥离出了用户服务中心,其主要出发点是用户的业务逻辑相对独立和简单,而且服务功能的复用率最高,在逐渐完善新研发的服务框架的同时,也沉淀了大量服务化实施的宝贵经验,这也成为今天我们在协助企业客户进行业务架构迁移时采用的典型方案。
经过两个多月的应用改造,用户中心于2008年年初成功上线。紧接着,又相继开始了两个在阿里巴巴内部非常著名的项目:“千岛湖”项目成功将“交易中心”和“类目中心”从现有平台中进行了剥离和改造,“五彩石”项目则将剩下的“商品中心”、“店铺中心”等核心业务功能模块进行了全部的改造。最终在保障淘宝业务不间断运行和不影响业务发展的同时,在14个月的时间内将原来单一应用的模式改造成为基于SOA理念的分布式服务架构。在应用部署形态上,由之前一个几百兆字节大小的WAR包部署模式改造成为上百个WAR包独立部署的服务化架构。这次改造被阿里巴巴同事称为“给飞行中的飞机换发动机”,也为后来的共享服务体系的建设打下了扎实的技术和理论基础。
随着淘宝平台服务化改造工作的完成,之前因为应用没有拆分的问题都得到了很好的解决:
降低不同模块开发团队间的协同成本,业务响应更迅捷。由于不同功能模块间进行了清晰、稳定的服务契约的定义,分别负责不同功能的开发团队只要保证对外服务的接口定义不发生变化,内部的业务不管如何调整,都不会影响到其他功能模块。结果是能更加快捷地响应业务的需求。新版本的业务发布周期从开发团队拼命加班加点也就勉强两周迭代(即新版本应用的发布上线)一次降低到相对比较轻松地实现一周两次迭代,其实如果不考虑业务的稳定性,技术上完全支持更加频繁的迭代要求。
大大降低系统间的耦合度以及整体复杂度,各个开发团队可专注于各自的业务模块。当应用被拆分成几个服务中心的架构后,各自开发团队专注于自己负责的业务服务中心的业务,原本需要对整个应用的架构和业务流程有全面的理解,现在转变为只要将自己领域内的业务做到最专业。这样对人员的要求降低了不少,原本一个人的精力需要分布到整个业务流程的各个环节,而现在只需要将精力集中在其中的几个环节中,从理论上一定会对这几个环节的理解和掌控更加精细,从而会提供更专业和稳定的服务。另一个好处则是对加入团队的新员工来说,相对更清晰的业务阵型有利于让这些新员工尽快理解自己负责的业务,从而更快地投入到生产中去。
避免了个别模块的错误给整体带来的影响。业务已经按照影响业务的优先级、变化的频率进行了服务化拆分,各个服务中心之间完全独立部署,这就完全避免了之前那种情况:因为前端广告业务中有一段错误代码,就造成整个平台业务最终受影响。
业务拆分后解放了对单数据库集群连接数的能力依赖。整个平台在被拆分为多个服务中心以及专门负责前端交互的应用模块的同时,在数据层也做了相应的拆分,即每一个核心服务中心都拥有各自独立的数据库,也使得之前迫在眉睫的数据库连接瓶颈问题得到了缓解。根本性地解决这个问题是采用了分布式数据库的技术,在后面会专门进行说明。
做到针对性的业务能力扩容,减少不必要的资源浪费。淘宝平台从改造前的一个WAR包模式到改造后的上百个WAR包方式,在某些业务模块的能力需要进行能力扩容时,我们可以进行“粒度”更细的精准扩容,而不是对整个平台应用进行扩展。淘宝当时的应用实例数量巨大,因为这样一点调整带来的资源节省就是一笔不算小的成本节约。