编者按:本文来自微信公众号“云原生计算”(ID:gh_94389f45059d),作者:郑同学,36氪经授权发布。
自从2009年入职百度以来,已经经历了11年了,我自己从一线研发工程师开始,也逐步成长成为了带领复杂技术方向的技术负责人。10年多的工作历程,让我有幸经历了大范围的技术演变,特别是云计算和云原生技术从朦胧到普及,对工程师和架构师的要求也发生了不少变化。趁着自己入职11周年的日子,结合我自己在百度的成长历程,总结下我认为在云计算特别是云原生时代,对软件架构师的核心能力要求,希望帮助大家在通往架构师的路上少走弯路。
初出茅庐从工程师变成子系统的技术骨干读书的时候并不了解搜索引擎,一直想着自己要从事一个有深度的技术方向,当时听说读到 Google 的三驾马车的论文非常厉害,赶紧拿过来拜读。但是受限于技术背景的缺失,对 MapReduce 的理念却完全不理解。后来无意中读了一本搜索引擎的入门书籍,一下子被搜索引擎的技术吸引住了。我发现搜索引擎同时涉及工程和算法两大方向,从底层的 Linux 内核到分布式系统,从简单的压缩算法到复杂的 pagerank ,是足够我学习一生的技术方向。于是抱着做搜索引擎的信念,开启了找工作的历程。随后有幸收到了百度和阿里的 offer,考虑到百度肯定是搜索领域的领头羊,放弃了即将成为"阿里云"的公司,选择了百度。
刚入职的时候我被分配到搜索工程团队,第一个项目是基于 Hadoop 重构原来的伪分布式架构下的建库系统,来解决伪分布式架构的不可线性扩展的问题。当时百度的索引数据量增长非常快,急需 MapReduce 这样划时代意义的架构来解决。我也是这时候加入了这个团队,经过3年多的时间,我和小伙伴一起把建库系统从伪分布式架构,升级成 MapReduce 架构,再基于 MapReduce 架构优化成了流批结合的流式建库架构,建库的效率提升了数十倍以上。我自己也从一线工程师逐步成长成小方向的核心骨干。这个阶段我认为主要锻炼了下面3项核心能力:
(一)软件工程的持续改进能力软件研发是团队作战,我们每个工程师都是研发环节的一员。在软件研发领域,决定团队研发效率的核心在于研发流程和协作的效率。互联网行业面临快速的变化,不确定性非常强,云原生时代也更倡导的 DevOps 理念和敏捷的研发模式来提升效率,快速试错,来应对不确定性。我们团队从2011年开始尝试从传统的瀑布模式转移到敏捷模式,并且选择 DevOps 工具来帮助我们实施敏捷流程。
下面是我总结的几点核心能力:
把握关键流程:需求分析,产品设计,软件研发,产品验收等关键环节,需要明确关键的角色为此负责,比如需求分析和产品设计必须经过产品负责人的审查,软件设计,编码和测试必须经过技术负责人和对应模块负责人的审查等等。
使用工具自动化:为了提升效率,让大量重复性高的环节自动化,包括文档工具,需求卡片的自动化状态流转,选择 IDE 和代码审查工具,代码搜索,构建自动化测试流水线和基础设施等。将重复性高的工作自动化来提升效率,我认为这才是工程师文化的精髓。
重视代码审查:代码是软件研发环节最核心的交付物,也是工程师之间需要协作的关键之一。作为架构师需要能够发现并且持续优化涉及代码审查的环节,这方面 Google 的代码审查实践给我们提供了非常好的参考。
架构师或者技术骨干需要对研发流程的每个环节保持着敏锐的嗅觉,能够及时发现其中的问题,并提出有效的优化方法。我们经常讨论架构师要不要写代码的问题,在我看来,不管架构师是否动手写代码,一定要对研发流程各个环节保持敏感,这样才能更好的带领软件项目高效高质量的落地。
(二)业务需求分析和理解能力理解业务可以让架构师的架构设计更快的落地,也让架构师能够更为顺畅的和业务研发同学进行沟通和交流。所以架构师切忌不可脱离业务,尤其是业务线的架构师,要时刻保持对业务的一定程度的理解能力。我们作为搜索架构团队,就需要经常和算法团队交流,和他们讨论算法团队的痛点和他们的发展预期,提前在工程架构上做好准备工作。
理解业务:技术的核心是为了让业务获得成功,架构是技术的核心之一,所以架构师一定要加强对业务的深入理解,了解业务的痛点,偏向业务的架构师甚至能够预测业务的发展趋势,提前在业务需要的技术方向进行适当的准备。比如当时我们决定迁移 MapReduce 架构完全是预测到已有架构完全无法承担未来的数据增长,需要提前布局。
提炼需求:很多时候用户提出的需求未必是真正的需求。面对需求,要养成多思考的习惯。思考需求的场景是什么,思考需求背后需要解决的问题是什么,来帮助我们识别并解决真正的需求。作为架构团队,算法和运维同学经常给我们提需求,但是用户提给我们的需求其实是经过自己加工的,隐藏了背后的场景,把他自己设计的解决方案当做需求提给了我们,但是经过深入讨论场景之后,往往可以把握真实的需求,设计更好的方法。
随时业务的发展和技术的演化,我相信任何一家公司或者任何一个代码模块,都有所谓的技术债务或者实现的不那么好的代码和架构。架构师需要能够识别那些真正的技术债务或者说技术折中,这就要求架构师能够把握技术债务的影响程度,让技术想着持续优化和改进方向演化。
适当的时机意味着把握目标,解决技术债务不是目标是手段,把握好目标才能更有的放矢。比如高频迭代的模块,因为结构耦合严重影响了效率和新功能的发布,或者说质量低下,频繁发生问题等等。或者说架构师在一定程度上预测未来的发展趋势,让技术朝着更先进的方式演化。我经常遇到一种情况是看到多种技术选型,架构师总是想所谓的统一架构。并以此为目标,却忽略了技术背后的真正业务目标,不能真正解决问题。
迭代式的发展可以有效降低技术风险,这个过程要注意避免两个极端。一个极端是动辄进行大规模的重构,一个项目耗时数人年或者更长时间上线。这种情况不仅项目风险极大,而且也大大减少了试错的机会。另一个极端是不断的添砖加瓦,只关注新功能的设计和研发节奏,而不做任何技术债务优化工作。这样时间久了之后,项目就会越发难以维护,周边类似项目不胜枚举。
游刃有余从技术骨干成长为架构师到2012年左右,我对于分布式建库系统已经非常熟悉了,大大小小的项目可以说手到擒来。但是我自己还不是十分满意,一方面我觉得自己只了解建库环节,对搜索引擎的检索和抓取环节完全没接触过,另一方面很多技术方向是在前人的积累上做的,感觉自己原创的并且先进技术比较少,所以我就想参与比较有开创性的之前没有做过的技术方向。从2013年开始跟着师傅一起探索新的技术方向。我们观察到不管是离线服务还是在线服务,当时微服务框架和中间件的能力是非常初级的,开源领域也没有更为成熟的技术,决定自己研发一套先进的微服务系统,现在看起来就是 K8S + ServiceMesh + SpringBoot (C++版) 的组合体。这个技术方向让我自己一方面对 C++ 底层技术非常熟悉,也让我认识了当时微服务的思想和技术趋势。在整个技术方向的研发和业务运用过程中,我自己的能力也得到了更全方面的锻炼,从技术骨干逐步成为负责一个技术方向的架构师。这时候也正好是以 Spring 为核心的微服务技术的快速发展时期。
(四)归纳抽象和技术泛化能力架构设计的本质我认为是抽象和泛化,我在设计微服务框架过程中,不管是对外接口,还是内部组件设计,经过了大量抽象思维模式的训练。抽象是将共性和差异化的东西分离出来,共性的部分抽象成独立的接口,功能模块或者服务。泛化是将技术运用到更多相似的场景,解决相似的问题。抽象和泛化是相辅相成的,需要架构师对问题进行反复深入的思考和对比,思考问题的背后最本质的东西,解决本质的问题。日常编写代码的时候,把握好代码设计的 SOLID 原则,在需要的时候对代码或者架构进行局部重构等过程就是锻炼抽象能力的好机会。有了代码级的抽象和泛化能力作为基础,可以进一步参与模块级或者子系统级的架构设计工作,更深入的锻炼架构设计能力。
抽象和泛化能力的培养需要我们能认清事物的本质,对此我特别推荐大家锻炼结构化的思维模式。《金字塔原理》或者《系统化思维导论》等书籍是锻炼结构化思维模式的经典书籍,非常详细的阐述了结构化思维的原理和方法,强烈推荐大家阅读并且运用到日常工作中。
历史是一面镜子,日常工作中及时的总结和复盘也非常有帮助。在每完成一些阶段性工作之后,对自己的工作过程和成果进行总结,可以站在更高的视角看待自己的工作过程,可以帮助自己发现更多的不足并加以改善。
(五)项目管理和技术领导能力随着自身能力的不断成长,我也逐步开始担任技术方向的负责人并且同时进行多个项目了。一方面要带领整个研发团队完成多个项目的落地,另一方面要求规划未来团队的发展方向。这就要求架构师具备项目管理能力和一定程度的技术领导力,从而带着整个团队一起完成工作。项目管理的核心是项目的工作拆解,研发工作的分配和项目进度的追踪等。项目执行过程中,还要根据具体问题,做出对应的技术判断和决策。比如研发工作的优先级和依赖关系调整,人力的重新分配,上下游环节的梳理和沟通等。最终保证项目在要求的时间内达到最优的结果。
技术领导力的核心我认为有三个要素:定义目标,结果导向,组织能力。首先是设定目标,目标代表团队的方向,合理的目标是团队成功的前提。其次是结果导向,团队最终为结果负责,不是为技术负责,真正创造了价值才是团队得以发展的根本。最后是组织能力,良好的组织能力是团队高效达成目标的保障。这包括充分理解团队成员的特点,做到知人善用;合理设计协作流程和组织结构,提升协同效率;识别核心岗位和关键人才,做到人岗匹配等。管理是一门学问,架构师需要学一些管理方面的知识,才能更好的带领团队达成结果。