2015 年是滴滴高歌猛进的一年,在多个业务方向都有很出色的产出。当业务以超常规速度发展的同时,技术架构逐渐成为业务迭代的瓶颈:客户端 /Web App 因为业务代码耦合紧密导致迭代速度大幅降低,服务端因为缺乏抽象和封装难以支持快速迭代等等,如何在大业务压力下为滴滴进行架构改造是个相当困难的课题。
2016 年 7 月 15-16 日, ArchSummit 全球架构师峰会将在深圳举行。本届大会,我们邀请了滴滴公共技术部总监杜欢老师,前来分享《滴滴出行业务系统的架构升级》的内容,讲述滴滴在单业务到多业务的高速发展中,系统架构各阶段面临的不同挑战以及对应的解决方案。大会上杜欢老师将介绍滴滴如何通过贯彻“无状态 + 异步化”来进行从前到后的代码治理,不仅会详细阐述各端上使用的核心技术和对应实施过程,并会着重分享架构重构中的经验与心得。
现在我们就来采访杜欢老师,让杜欢老师提前分享架构升级中的痛与快乐吧!
InfoQ:架构师的市场需求很大,因此职业上有很多选择,您为什么最终选择滴滴?如何看待 2015 年出现的共享经济浪潮?
杜欢:我选择滴滴的原因很单纯,当时因为自己创业失败,希望找一个处于高速成长期且大一点的平台来沉淀一下自己,加上与滴滴当时计划做的一些事情有些契合,所以最终加入滴滴。
共享经济无非是一种资源再分配的过程,各种共享其实自古以来都存在,只是因为国内经济最近发展到一定阶段,资源闲置和资源维护成本不断增高,加上互联网作为催化剂降低门槛和加速共享过程,最终产生不可估量的价值。
汽车就是一个典型代表,随着油价、停车费等成本不断成长,加上大城市拥堵状况日趋严峻,自驾上班或出行消耗的金钱和时间成本已经突破了一个平衡点,越来越多人会愿意选择更加省时省力的打车,而这种商业气息浓郁的需求会吸引拥有闲置汽车又希望改善生活的车主,在一个共享平台撮合之下,这里面就能产生惊人的商业价值。
InfoQ:2015 年滴滴高歌猛进,在多个业务方向上的成绩都让人非常瞩目,这对技术架构提出了哪些挑战?
杜欢:2015 年,滴滴看准出行领域各种垂直品类发展的窗口期,首先结束了与快的烧钱大战握手言和,然后立即开始迎击国际巨头的挑战,接着在多个出行品类迅速扩张出击,成功在年底达成多品类第一的目标。
业务的迅速扩张永远是技术人的痛,这意味着无论如何提前做准备,都不太可能轻易预见到未来的走向。随着一个个事业部逐步成立、独立,各色技术人员涌进公司,再加上公司初期也一直因为高速发展没有好好修炼内功,导致代码腐化严重,甚至影响业务迭代,不得不在高速飞行中换引擎。
在这种情况下,最大的挑战莫过于权衡业务迭代速度和架构完美程度,两者都应该把握一个度,究竟如何抉择是一个永恒的难题。要想破解这个难题,就要求技术决策者充分理解业务,特别是业务的出发点和目的地,对于一些正在螺旋上升的事情要能看清楚宏观方向是什么,不能仅仅盯着当前业务发展的方向。
对于滴滴来说,宏观的方向一定是要做一个效率工具,一定要帮助数千万人解决出行效率问题。尽管从去年以来这个市场竞争很激烈,各个业务都在卯足了劲想法设法的拿下市场份额,技术会服从于业务发展现状做一些短平快的事情,但是我们未来还是会往提升效率方面走,各种业务的核心应该是趋同的,数据应该是能互通的,所以在业务狂奔的同时我们还是要做一些公共化和下沉的工作,确保事情确实还在螺旋上升。
InfoQ:从单一业务线发展到多业务的时候,架构的阵痛主要在哪些方面?
杜欢:具体来说有三点:
- 代码重复度高,耦合严重
任何一个微小功能都可能产生牵一发动全身的严重问题,滴滴是一个客户端很重的应用,一个 App 里面融合了好几个独立产品线的功能。在重构前,客户端缺乏一个分层合理、依赖清晰的框架,每次对外发版前的测试都很让人崩溃,任何一个业务修改任何一个 bug 都可能会有全局的影响,所以所有业务得再全部重新回归一次,明显很浪费时间。服务端则更严重,滴滴最大业务的代码有数百万行,前后有数百人经手,有些似是而非的逻辑谁都不敢动,而且代码风格还特别不好,总喜欢写长函数、大量复制粘贴、用没有约束的哈希表来传递各种参数等,这让在此之上添加新功能变得极为有风险。- 无人对整体架构负责
滴滴缺乏一个可靠的底层基础设施封装,低水平建造比比皆是。这点主要体现在滴滴客户端。去年重构之前,安卓平台上滴滴各个业务用了市面上几乎所有流行的网络库,因为缺少整体架构,大家都是以自己的喜好和以前经验来选择方案,在某个第三方成熟框架上二次封装了事。这种做法明显非常浪费人力,所有的网络优化都需要在所有业务的封装上实现一遍,而且业务本质上也没有精力和能力来持续优化技术点,所以需要一个整体封装。- 业务需求本身也缺乏抽象
看起来类似的业务也有各式各样个性化的需求,这导致技术很难轻易找到整合的方法,最终在不断分化的路上越走越远。最典型的就是滴滴的出租车和专车,如果不加上任何限制,这两个业务每个细节都可以做出不同点,技术上显然不可能找到方法将他们硬是合在一起,但实际上它们的核心业务逻辑是基本相同的,只是运营手段不同、界面皮肤不同。需求分层做好了,要想做好技术就非常自然了。
InfoQ:客户端的迭代一般会因为什么原因受限?服务端呢?你们是如何解决的呢?
杜欢:前面提到的三点,客户端和服务端都会受到影响,本质上就是需要抽象和封装却难以找到解法,不断的恶性循环。
解决的方法有两个:一方面必须收敛需求,丢掉包袱轻装上阵;另一方面要“分而治之”,先让大问题变小,最终再逐个击破。我们在实际工作中,这两个解法是同步进行的,只不过收敛需求方面做了一些之后又因为种种原因有所倒退,最近才又再次开始思考和推动类似事情继续朝正确方向演进。
InfoQ:您将在 ArchSummit 大会演讲中介绍“无状态 + 异步化”,能否简单谈谈这个设计理念?
杜欢:这里所说“无状态 + 异步化”是一个大的设计原则,在客户端和服务端多种场景下都可以找到显著的例子,大家日常应该都在以类似思路在工作,但可能感触不深,没有把它们作为一种指导原则。
在服务端里,为了解决性能和可用性的问题,我们在架构层面往往会考虑如何让各种服务的状态集中到一个逻辑简单稳定的分布式存储中,让经常改变的业务逻辑尽可能无状态。为了尽可能提升业务系统的吞吐,异步化则是不二法门,通过队列和高效的调度,整个系统可以在不同的压力水平下都表现良好。
在客户端里, 我们采用与服务端类似的思路,将状态存储到稳定存储中,让业务代码尽可能无状态,并且用异步回调解开逻辑之间的强依赖和高耦合,让业务和业务、界面和界面都互相保持中立,可以随意跳转拼接,独立开发 。
在实施过程中,这个设计原则是一个指导思想。有趣的是,我发现这个原则可以渗透到各个方面,甚至我们的客户端发版流程都用这个原则设计出一个相对高效的模式,比去年年末发版效率有了显著提升。
InfoQ:比起以云计算为主的存储驱动公司,滴滴更偏向数据驱动,这对架构设计有什么不同的影响?
杜欢:数据驱动的大前提是数据要能方便的采集、清洗、解析、建模,最终才能方便的分析并驱动业务。在这个方面,我们去年做了很多思考和设计,提出了一些有趣的解决方案,不过最终因为种种原因并没有在线上启用,很可惜。
要说对架构设计的影响,我觉得现阶段更多是需要考虑日志标准化的问题,尽量先做到数据生产方式统一,方便跨部门的数据分析。日志标准化其实对架构统一要求不高,这也意味着约束力不强,所以短期就算能统一长期要想不让大家分化也挺难的,我们也在考虑怎么用技术手段让这件事做的更好,未来可能会通过产出一些基础应用框架的方式来规范这些东西,但还没想好。
InfoQ:对于有志于架构师工作的读者,您有什么建议呢?比如学习曲线、成长路径等方面。
杜欢:我个人认为架构师要有“品味”,要让自己成为技术的百科全书,要对新技术敏感。架构师就像一个品酒师,需要通过不断读代码了解不同系统的味道并记在脑海里,每年都需要用新知识刷新自己的储备,在面对问题时能分析出问题的层次和轻重缓急找到一些思路,最终驱动整个团队解决问题。技术方案往往没有绝对的优劣,就像不同的美酒都会拥有各自簇拥一样,架构师要能根据自己的“品味”给出一个充满自信的答案,并坚决执行下去,这种勇气也是成为架构师的一个必备条件。
我说的这些看似很难,但也并非遥不可及。架构师的核心循环无非是遇到问题、分析问题、寻找和对比解决方案、实施、回顾,当问题尺度缩到很小的时候,其实就是工程师日常解决的小问题的合理过程。所以,通过在每个细节都保持思考和积累,并不断扩大自己的解决问题能力,再加上一些领导力,离一个成熟架构师也就不太远了。
InfoQ:感谢杜欢老师接受我们的采访,期待您在 ArchSummit 全球架构师峰会上的分享。
感谢陈兴璐对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论