上一讲我们以架构之名探讨了理解业务的重要性,这一讲我想深入讨论一下日常工作中架构工作的关键关注点是什么?
我是在接触分布式开发之后,才对“架构”有了概念,从高可用性、高性能、高可扩展性到 DevOps(包括集群、网关、负载均衡等),从系统的功能模块设计到微服务的业务建模、领域设计。很长一段时间里,架构似乎涵盖了所有与技术相关的内容,给人的感觉是要做好架构就必须精通所有技术。

但在实际工作环境中,你不可能精通所有技术,而且由于分工问题和精力有限,我们也无法事事亲力亲为,因为这样容易导致混乱,错过重点。
那么围绕架构,你的工作重点是什么呢?
在我看来,就是管理系统的复杂度。因为像功能实现、性能优化、稳定性等方面有公认的标准,其他角色(如架构师、运维专家)会共同参与。但系统复杂度则像是各有所感,可能只有你自己,才能对其有充分的认识和把握。而一个足够清晰、稳健的系统,才能支持业务的发展,进而讨论架构的演变。
所以今天这一讲,我想从系统复杂度治理以及演进两个维度来聊聊架构。

治理好系统复杂度才最务实
C.A.R. Hoare 曾说过:“软件设计有两种方式,一种是将软件设计得非常复杂,使得其缺陷不那么显眼;另一种是将软件设计得尽可能简单,确保没有明显的缺陷”。
我非常喜欢这句话,可能是因为这几年见过太多“过于复杂”的系统,我对简洁和明了有着特别的坚持。
在我看来,业务复杂所以设计出复杂的系统不是本事,业务复杂,而你依旧能通过足够好的抽象与分层将系统做得简单才是本事。
然而,在日常工作中,你可能没有机会从头设计一个新的系统,多数情况下是从接手旧系统,解决一个个问题开始的,例如某个接口响应变慢,需要解决性能问题。在解决问题的过程中,你会逐渐思考问题的根源和解决方案,这时你会发现这些问题多是由之前的某些设计和迭代决定的。许多问题源于系统结构设计不佳,比如服务的划分、数据库的冗余、调用路径或接口规范。
这些问题在后续的迭代中通常只能得到缓解,难以彻底解决,随着时间的推移,我们最终不得不重构系统。
其实,随着业务与人员的发展和变化,你几乎无法避免系统重构的问题,“系统腐化——重构系统”的趋势近乎必然,背后的原因在于:日常系统的迭代以满足业务需求为主,其他精力都用来解决类似高性能、高可用这类明显影响系统“生存”的问题,而对高可扩展(延长系统的生命周期)的投入会比较少,因为系统的高可扩展是一个相对隐蔽的问题。
有趣的是,产品、运营乃至业务方面对技术在“可扩展性”上的需求非常明确且强烈,他们希望需求能够迅速实现,而不关心实现的方式是否优雅、性能是否足够。
即使排除产品和运营等的要求,从系统架构的角度来看,技术价值在商业环境中(业务方)最核心的表现就是使系统能够“持续快速交付”。在这方面表现出色的系统通常具有一些显著的特点:系统结构清晰、即使总体复杂但每个部分都相对简单、流程直接,没有不必要的冗余。
所以,我认为日常开发中,对架构最核心的关注点应该是复杂度的治理,如何在满足需求的前提下,尽可能地降低系统复杂度,保持系统灵活就是你应该关注的事情。
在实际工作中,尽管我们可以直观地感受到系统的复杂性,但很难找到类似于QPS、响应时间等具体的数据指标来精确衡量它。因此,很多时候技术领导者在评估系统复杂度时,除了依赖个人感觉之外,还需参考系统和团队的某些表现特征(这些特征与技术债务有许多相似之处,毕竟技术债务也是系统复杂度的一种表现)。
理解成本高
:新成员加入或系统交接时,需要很长时间才能完全理解系统的组成和运行机制,例如,老成员难以全面讲解,新成员也不易理解,可能需要几周甚至1~2个月的时间。
变更牵连多
:即使是实现一个小的功能也需要修改系统的多个部分,甚至涉及多个系统(如上下游系统),有时还需要与其他团队或部门协调,结果导致迭代成本高,并可能引入更大的风险。
一张图装不下
:你无法在白板上清晰且完整地描绘出系统主要功能场景的架构图,可能是由于涉及的系统、服务、组件过多或链路设计不合理所致。
加人无法解决问题
:即使增加了人员,也难以提升系统的交付速度和质量,比如原本3人负责的系统,增加到6人后,交付效率可能与3人时相差不大,原因是复杂度过高且系统结构模糊,难以通过有效的分工来最大化生产效率。
你可以结合上述四点表现特征及个人感受进一步判断系统的复杂度是否过高,如果系统复杂度过高,可能会引发一系列问题:迭代压力增大、频繁延期、稳定性问题频发等。这时,你需要着手治理复杂度,努力防止问题恶化到不得不重新构建系统的地步。
“复杂度的治理”这一话题相当广泛,因为不同的系统和团队面对的环境各不相同,很难有一招通吃的解决方案。在实际业务场景中,系统发展一段时间后,通常需要应对业务发展的不确定性。因此,无论是考虑不周全,还是为了赶时间的妥协,在架构上总会有不足之处。这也是为什么在公司很难找到“完美无瑕”的系统。
但请注意,不要将“简单清晰”误解为“完美无缺”,复杂度治理并不是一个清除污染的过程。而是在限定的投资回报率(ROI)和考虑业务不确定性的前提下,通过架构设计与实施,追求系统的可控性和可持续性。我非常认同“高内聚、低耦合”的架构理念,并认为在复杂度治理的策略上应遵循这一原则,对系统进行简化和分治。
简化意味着去除不必要的复杂性,确保设计和实现简洁明了。例如,在某一业务场景中,系统可能只需 A 调用 B 即可,但由于种种原因(如团队责任划分、旧系统设计等),变成了 A 需要先调用 C 再调用 B,而且 C 中还可能存在多余的步骤。这种不必要的设计与实现,会使系统逐渐变得复杂,这种情况在技术组件的选择、系统链路设计、数据库设计以及接口实现中屡见不鲜。
分治策略是将难以处理的问题分解为易于解决的部分,然后逐一攻克。当然,分治不仅仅是简单的“拆解”,更关键的是管理和协调拆分后的各个部分之间的联系。许多系统从最初的单体应用发展到分布式系统,就是一个持续的拆分过程,因此你可能会发现架构总是在不断地拆分,并通过这种方式解决问题。早期在软件设计领域,人们常说:“任何问题都可以通过添加一个中间层来解决,如果不行就再加一个。” 到了分布式和微服务时代,这句话变为:“任何问题都可以通过拆分子模块来解决,如果不行就继续拆。”
这种观点是有一定道理的,因为随着业务的发展,系统复杂度必然会增加,而适当的拆分可以将复杂度分散到多个部分,从而降低每个人所承担的系统复杂度。
但你要注意,复杂度在系统中只是被转移和分散了,并没有消失(消灭),你终究还是要处理那些拆分出来的复杂度,所以如果盲目地拆分,可能只解决眼下的问题,却在未来得到更糟的结果(比如到时候已经拆无可拆)。那具体怎么拆分呢?
常见的拆分方法包括垂直拆分和水平分层:垂直拆分将业务逻辑清晰且能够独立发展的部分分开;水平分层则是将通用的能力下沉并隔离。例如,在电子商务场景中,购物车和订单可以被分为两个独立的服务,尽管它们在业务流程上紧密相连,但每个都有独立完整的业务场景和生命周期。商品加入购物车并不一定导致订单的生成,因此它们可以独立存在;而库存和商品则是高度依赖的,库存不能脱离商品单独存在。
然而,拆分的原则并不是固定不变的,它会随着业务和系统的演进而调整。比如,评价最初通常是用户对商品的反馈,所以在早期系统中,评价功能可能与商品模块紧密结合。随着评价内容的增多及其作用的扩大(如用户画像、商品推荐),评价功能可能会成为一个独立的系统。随后,随着不同业务的发展,可能会出现多个独立的评价系统。起初,这些系统的业务可能有所不同,但为了防止重复工作和数据整合,这些评价系统最终可能合并成一个更为强大的系统,这是一个动态变化的过程。
因此,拆分与合并并不是绝对的,过度拆分会破坏系统的高内聚性,使系统变得分散,增加稳定性和治理的难度,同时也会带来巨大的协作成本。Linus 曾指出:将复杂系统拆分为模块,看似降低了系统的复杂度,实际上只是减少了子系统的复杂度。整个系统的复杂度,由于各模块间不可避免的交互,反而可能变得更加复杂。
复杂度治理的核心在于帮助你理解并思考问题,但在实际工作中,我们也需要采取一些具体的措施,重视代码的质量和每次需求的迭代,细节决定成败。以下是一些简单的实践建议:
相比 coding 更重视设计
与其花费大量时间审查代码,不如多花时间思考如何设计和实现某个功能。虽然“重视设计”听起来简单,但根据我的观察,一个团队如果重视设计,其负责的系统通常表现良好。
我的第一任 Leader 和我强调过,写代码之前要先用笔和纸把编码思路写下来,捋清楚了再干。这一点我延续至今,我也建议你将这样的习惯推广下去(未必是笔和纸的形式)。
永远做 2 套以上的方案
很多时候,可行的方案不一定是最优的,局部最优也不一定是全局最优。多准备几套方案不仅能促使你深入思考其优缺点,还能帮助你更好地规划未来。系统复杂度的增加往往与我们倾向于选择最简单的实现方案有关,这可能导致“为了实现某个需求,不得不对系统进行复杂的修改”。因此,不要总是选择最容易的实现方案,也不要满足于能工作就好。
从 MVP 的视角考虑设计
从最小可行产品的角度出发,考虑系统的设计与实现,先做减法再做加法。如果某些设计去除后,系统仍能有效运行,说明这些设计是多余的,因为架构本身也需要进行精简。
关注上下游的实现
站在更高的视角看问题,重视系统间的互动。从操作的角度来看,上下游系统是你负责系统的外部环境,了解它们的运作不仅可以加深你对业务的理解,还可以帮助你预防更多问题(如 API 的一致性协议、上下游系统的超时设置、降级机制等)。
坚持“日拱一卒”
尽可能在每次迭代中修复之前的问题,逐步完善系统。如果平时不注意逐步优化系统,即使经过重写或重构,也只是暂时改善了系统状态,随后系统仍然会出现各种问题,不会发生根本性的变化。因此,不应将复杂度治理视为一次性任务,而应将其作为长期的习惯。
总体而言,架构层面的复杂度治理旨在使系统更加简洁、高效,以便更好地适应业务的变化。这是一个需要两手都要硬的过程:
先满足业务,然后从技术的视角去前瞻业务,通过架构的演进让技术走在业务前面,为业务赋能
有趣的问题随之而来:许多人认为中台是系统演进的最终形态,但从系统演进的角度来看,是否必须将系统构建成中台呢?
不必非要把系统构建成中台

过去两年,我在本地生活技术领域负责业务中台,团队最初成立时命名为“中台研发部”。我与众多公司内外的朋友探讨过中台的相关话题,很多人常提出类似疑问:“如果不构建中台,是否会落后于时代?我们计划这样建设中台,您怎么看?”我的观点是:不必强制将系统构建成中台,认为不建中台就会落后是不切实际的,然而,可以从中台的概念中汲取灵感,用于系统设计和发展的参考。
我曾读过逍遥子的一次采访,他提到:“从一开始就立志打造平台的人,几乎没有成功的。”这句话让我深感共鸣。系统的演变实质上是对公司业务发展在技术层面的反映,适应性始终比最优更为关键。例如,饿了么早期无论是系统还是业务都是一体化的,随着快速的发展,业务形式逐渐多样化,技术方面则采用了DDD的方法逐步拆分并微服务化,大量业务模块被拆解成独立的系统和基础中间件,形成了分层下沉的架构。伴随业务的成长,这也促进了技术的进步,从而实现了多活、中台和全面云化的目标。
关于您的系统是否适宜向中台结构转变,建议从以下三个维度结合自身情况进行考量:
从宏观角度看,中台更注重组织和职责的重新定义,首要解决的是生产关系的问题,因此有“小前台,大中台”之说。可以说,新的组织架构设计是中台实施的基础和前提。技术团队若想成功建立中台,仅凭理念和共识是不够的,通常需要组织自上而下的推动,而能够自下而上实现变革的企业凤毛麟角。
许多朋友在了解到SuperCell的中台奇迹后感到激动不已,但只有深入了解其公司文化及运作机制后,才能明白其创造奇迹的根本原因,如庆祝失败、最大限度授权(CEO倒金字塔模式)、追求极致体验(而非最大利润)。从SuperCell的公开资料可以看出,他们致力于构建精简高效的业务开发团队(前台)和提供强大工具与服务的中台。前者追求虽小却五脏俱全,确保灵活性和最低沟通成本;后者则追求强大而非广泛覆盖(并非所有功能均需集成至中台)。
因此,如果您的公司(或大部门)缺乏中台的战略方向或相应的组织落实措施,那么单纯的技术中台实施起来将面临较大挑战。
这两年来,我既是中台的建设者(饿了么)又是使用者(阿里巴巴),无论从哪个角度来看,我都认为中台尚未成为一种成熟到可以立即应用的解决方案。实际上,大多数对中台赞誉有加的声音往往来自中台的建设者,而很少听到中台用户的评价。这显然不符合逻辑。
中台在落地过程中存在很多困难,我分享给你 3 个深刻感受。
假设技术中间件的底层复用能力可以解决系统10%~20%的问题,那么中台所要解决的问题实际上已经深入业务的核心区域。然而,参与中台工作的成员往往远离一线业务,难以对业务进行充分的抽象和积累,因此中台的抽象可能会有一定的延迟,对业务快速迭代的帮助有限。
简单地说,中台团队也有自己的KPI目标,从服务业务的角度来看,必然会优先支持大型和关键业务,因此如果没有高层明确指示,小型或创新业务很难获得足够的资源支持,即便获得了支持,由于中台需要进行大量定制开发,合作周期可能延长,涉及的人员也可能增多。结果可能是,原本的开发成本虽然部分转移到了中台,但合作成本显著增加,总体效果和周期并不理想。
中台对业务的抽象和开放定制能力是有限的,比如订单中台的状态机具有不同的开放程度,如果每个状态都可以自由配置,则会导致相关业务能力变得过于碎片化。因此,中台更多的是有限度地开放,例如支付流程是固定的不可跳过,而交付方式则可以是快递送达或到店取货等。无论如何,所有设计都必须在中台定义的框架内进行,这可能导致某些业务无法完全适配,经常出现各种小问题。
尽管上述提到中台存在一些问题,但这并不意味着我完全否定中台的价值。中台展现了强大的技术特性(抽象、积累、复用、整合),可以说是将技术追求进一步扩展到了业务层面。当企业的规模达到一定水平时,中台的好处往往超过弊端。如果说以前我们抽象积累的是技术组件,那么现在中台抽象积累的是业务组件。但你也应该意识到,企业的数字化需求和场景多种多样,很难有一种方案适用于所有情况。在处理业务时关注差异性,在构建系统时关注共性,能否构建技术中台很大程度上取决于业务形态、发展阶段和组织结构。
如果环境和业务发展没到那个阶段,我认为大张旗鼓做中台的 ROI 比较低,技术人员很难准确预测业务的形态。实际一点的做法是: 借鉴中台的系统演化思路,对业务的实现多做抽象和共性的沉淀,尽可能保持系统灵活同时多支撑相似的业务形态。比如做订单就考虑如何支持多种类商品或营销、做支付就考虑除了微信与支付宝未来要支持银行卡怎么办,每次做设计时都假想下如果又多一个业务形态你怎么支持。
对于你来说,不一定需要全公司上下一致决定实施名为“中台”的策略,然后再大规模推进中台建设,完全可以从小系统开始尝试。此外,不应借中台之名将所有业务和系统无差别整合,若中台系统既庞大又笨重、反应迟缓,实在难以看出其存在意义。明确你的目标是什么,如果你期望的是一个高度灵活的系统,那么名称是否为中台其实并不重要。

本部分讨论了架构主题,但未涉及分布式系统的三大特点,也未探讨微服务的DDD原则。尽管这些内容对架构设计至关重要,但由于其重要性,无论是大量文献资料还是实际工作中均已给予了充分的关注。大多数情况下,未能实现良好架构的原因在于资源或能力的限制,这是已知的问题领域。
然而,我认为复杂性是一个隐秘的威胁,虽然不会立即导致系统故障,但它会慢慢侵蚀系统,如同慢性疾病一般,需要通过长期的改进(如开发和架构习惯)来克服。对于许多开发者而言,这是一个未知的挑战,往往意识不到其严重性和潜在影响,因此建议在系统设计时从人员和系统两方面综合考量复杂性的变化,确保当前的努力能对未来产生积极影响。

作业:针对你所负责的系统,你是如何管理和减轻复杂性的?根据你对业务的理解,该系统的最终形态应该是怎样的,理由是什么?
注:本文摘自拉勾教育《成为会带团队的技术人》课程材料,撰写此文主要是为了做笔记。如有版权问题,请联系删除。
扫码加好友,拉您进群



收藏
