构建卓越平台的核心原则与实践指南

本文深入探讨了软件平台的定义、构建策略与管理原则,涵盖自动化、客户自由度权衡、非干扰性与有效需求评估等关键概念,为平台团队提供从产品演化到平台扩展的实用指导。

在软件工程领域,我们经常谈论使用或构建一个“平台”。让我们来深入探讨其真正含义,以及构建一个卓越平台的原则。

什么是平台?

人们有时认为平台是“很多人使用的东西”或“由一个团队构建、并被许多其他团队依赖的系统”。我提供一个更细致的定义,以帮助我们区分产品和平台: 平台是一个拥有多个独立客户的系统,这些客户可以使用该系统并修改其行为,而无需与其他客户进行协调。

通常,我们将平台视为一个“运行”他人系统的系统。亚马逊网络服务(AWS)是这类平台的一个绝佳例子。亚马逊提供了一种方式,让你可以在AWS“之上”运行自己的系统(包括运行这些系统所需的各个部分,如存储、路由等)。当你使用AWS时,你无需与其他所有AWS客户核对,例如“我现在部署可以吗?”或者“我能获得五个主机来运行我的服务吗?”你所做的事情很难对其他客户产生负面影响,其他客户的行为也很难对你产生负面影响。

当然,还有其他类型的平台。例如,我曾经帮助开发过一个平台,允许人们在公共仪表板上展示他们自己的指标。他们编写了生成指标的代码,并在其他地方运行这些代码,而我们的系统只是在一个全公司范围的仪表板上以标准化方式展示这些指标。实际上并没有任何东西在我们的平台上“运行”,但客户仍然可以使用该系统并为其自身需求修改其行为,而无需与其他客户协调。

宽平台与窄平台

理论上,像YouTube这样的网站从最狭义的角度看也是一个平台。你上传视频,这“修改了系统的行为”,使其现在展示你的视频。你无需与其他正在YouTube上传视频的每一个人核对你现在是否可以这样做。你也有一定的权限来配置该视频的显示方式以及你的YouTube频道的工作方式。

由此,我们可以看到平台允许不同程度的自由。像AWS这样的平台将是一个非常宽的平台——你几乎可以在其上运行任何类型的软件。而YouTube则是一个非常窄的平台——你修改系统工作方式的自由度非常有限。

为你的平台把握好这种权衡,是你作为平台所有者必须做的最重要的事情之一。 你选择允许客户拥有多少“自由度”,将决定你成功设计、构建和维护平台的难度。

自动化平台与手动平台

优秀平台还有另一个特性: 最佳平台不需要平台所有者的手动干预,客户就能成功使用它们。 假设你想每天向客户发布五次系统的新版本。如果你每次都必须给亚马逊的某个人发电子邮件,要求他们手动部署你的代码,那会怎样?这不仅对你来说体验极差,也会极大地损害AWS作为一个产品的成功。亚马逊的客户将迅速寻找其他平台来使用。

平台可能要求不同级别的手动干预。最常见的有两种:

  1. 需要平台所有者手动干预才能接入平台。
  2. 需要平台所有者手动干预才能执行常见的配置更改或修复常见的支持问题。

这带来了两个问题:

  1. 你让你的客户等待,直到有技术人员可以支持他们或帮助他们接入。这通常不符合他们的时间线,因此他们会寻找其他解决方案。至少,这会显著拖慢你的业务。
  2. 平台所有者会淹没在手动工作中,随着时间的推移,他们越来越无法真正投入到平台的工作中。你甚至可能陷入一个恶性循环:由于手动工作太多,你不再有工程师来开发必要的自动化以消除这些手动工作。

当然,手动工作也更容易出错,从而使你的系统面临更多故障。在实践中,这通常是一个次要问题,但确实会发生。

总的来说,如果你有一个需要手动干预的平台,它仍然是一个平台,但并不理想,并且随着你的工程师花费越来越多的时间进行手动工作,而越来越少的时间改进平台本身,你的平台面临随时间退化的风险。

构建一个平台

好了,现在我们知道了什么是平台。如何构建一个呢?我总是告诉团队的是: 你从一个产品开始,然后随着时间的推移将其转变为一个平台。 这里的“产品”是指帮助人们实现某个目标的系统,但用户并不控制系统的根本行为。我们交互的大多数软件本质上都是产品:Gmail、Microsoft Word、Zoom、Photoshop等。

对于产品,作为产品开发者的你,专注于为用户创造出色的体验。你专注于帮助他们实现一个已知的、特定的目标,并精心策划他们使用产品的整个体验。以微软为例,他们投入了巨大的资源来优化Office的用户界面,使编写文档或创建电子表格的人们可以专注于他们需要完成的任务,并让产品尽可能地“不碍事”。

上面我们提到,对于视频创作者来说,YouTube是一个非常窄的平台。但对于视频观看者来说,YouTube完全是一个产品:你打开网站,它为你推荐要观看的视频,你观看,完成。我在YouTube工作过,我可以告诉你,公司非常重视为你精心策划这种体验。

如果你打算开始构建一个平台,你首先应该弄清楚:我打算为客户提供的核心价值是什么?为了我的系统成功,哪些部分需要精心策划的体验?

例如,假设你想为公司构建一个部署平台——一个获取代码并将其发布到生产环境的系统。它提供的核心价值是:我不再需要手动工作来成功且安全地将我的代码推送到生产环境。因此,你首先应该构建的不是一个平台,而是一个提供这种精心策划体验的产品。

这在实践中是怎样的?你会找到一个在手动部署方面遇到一些困难的团队。你希望他们在公司里不要过于边缘化(例如,如果公司里有一个由三名移动开发者组成的团队,而公司其他人都编写Java后端服务,就不要从为这三名移动开发者构建东西开始)。你也不希望他们对业务过于重要——永远不要从最大的客户开始。你将构建一个新产品,需要一些空间进行实验、学习和犯错。如果你尝试为某个团队构建这个产品,而整个公司的收入都依赖于该团队,那么你将没有实验的空间——相反,你会被迫赶工,被迫构建你不应该支持的功能,或在产品生命周期的早期就创建这些东西。

所以基本上,你要寻找一个能代表公司很多团队工作方式的客户,他愿意并且能够承担一些风险,并且能够与你密切合作,为你正在构建的东西提供反馈。

然后,你尽最大努力只为那个客户构建一个优秀的部署系统。在这一点上,修改或重新配置系统的所有工作是否都是手动的并不重要。事实上,可能应该是手动的,因为将要发生的事情是:你会构建错误的东西,交给你的客户,发现它是错误的东西,然后重新修改直到它变成正确的东西。你永远无法在第一次尝试时就得到正确的产品。因此,不值得一开始就尝试自动化所有事情,因为你将不得不抛弃那些自动化并重新编写。对于客户来说,部署本身是自动发生的,但如果他们需要改变部署的工作方式,即使这需要你(产品所有者)手动修改代码,也没关系。

不过,在构建这个产品时,要牢记一件非常重要的事情:不要把自己逼到只能支持这一个客户的角落。 应该有可能在未来安全地修改系统以接纳另一个客户。你这样做的主要方式是遵循软件设计法则。不要在需要之前就让事物变得通用——只需记住你将来将需要接纳其他客户,并且不要让自己失去这样做的能力。 实际上,最好的方法就是保持系统简单,以便将来可以轻松修改。

把这个产品做好并打磨它至关重要,尤其是在这第一个客户参与期间。 你希望与这个客户密切合作,直到你确信你为这个客户创造了出色的体验。然后,你走出去,寻找其他在不同方面具有代表性的客户——那些与你的原始客户有不同需求的人——并与他们经历相同的过程,仍然是在构建一个产品。

当你停止定期学到重要的新东西时,你就会知道可以扩展到第一个客户之外。 对于你的其他试点客户也是如此——当你从他们那里不再学到导致你产品发生重大变化的重要新东西时,你就可以扩展到那组用户之外。你不必在每个客户那里都完全“完成”才能扩展,你只需要确信产品对该客户来说是成功的,并且你不再频繁发现新的需求。

所有这些将构成你未来平台的核心基础。大多数笨拙、困难或失败的平台,在“打开闸门”成为平台之前,没有花足够的时间打磨他们的核心产品。

向平台过渡

如果你在产品构建方面做得很好,人们就会开始敲你的门,要求也被允许使用你的产品。你可能需要对产品做一些轻度营销,但我通常发现,对于企业内部平台来说,如果你构建了一个优秀的产品,口碑就会传播开来,人们就会开始要求也被允许使用它。

你首先想要接纳的是那些需求与你的初始客户几乎相同的人。本质上,起初你希望保持一个产品,并且你想看看当你必须将该产品扩展到许多客户时是什么样子。在这个阶段,你将学到很多关于产品的知识,并显著改进它。你甚至可能开始自动化接入流程,并为那些曾经需要手动工作的非常常见的配置请求提供一些配置设置。

然而,最终你会达到一个感觉“野蛮人兵临城下”的阶段。你会看到一些事情发生,表明你正处于这个阶段:

  1. 来自客户的、越来越坚决的要求接入的请求。他们甚至可能开始抱怨,不让他们接入实际上是在伤害他们。
  2. 你会开始收到越来越多的功能请求,而这些请求在核心产品中实现似乎存在问题。它们只涉及小的边缘情况,但如果你在核心产品中实现它们,它们会对你所有客户造成干扰。

这就是你构建平台的时刻。 注意:在“产品”阶段,在达到“野蛮人兵临城下”阶段之前,你非常努力和快速地打磨产品至关重要。 否则,你将在准备就绪之前被迫构建一个平台,而你的平台在其剩余生命周期中将受到影响,所有用户的体验也会如此。

我们“平台化”什么?

作为平台所有者,你反复要做的最关键决定之一是:我们在核心产品中实现什么,以及我们允许我们的客户在我们的平台内自行开发或配置什么? 这应该始终由你的客户需求驱动,但要警惕那些仅仅要求被允许拥有完全控制权并配置一切的客户。如果你真的让他们配置一切,你将彻底击败你平台的价值——你只是让他们以一种新的、不同的方式编写自己的软件。那么,你给予客户多少回旋余地呢?

有几个原则驱动着这一点。

非干扰性 我们的第一个原则是: 一个客户不得干扰另一个客户。 在我们的部署平台例子中,假设一个客户来找我们说:“我希望能够随时暂停公司里除我之外的所有其他部署。”在几乎所有情况下,你都会拒绝。应该只有平台所有者能够影响所有客户(甚至同时影响多个客户)。对于这样的需求,如果它真的是一个合法的需求(我个人会深入挖掘,问很多“你试图解决什么问题?”的问题),你会说:“如果你需要这样做,请告诉我们,我们将代表你执行。”这让你保持控制,并将责任放在正确的地方——你最了解你的系统发生了什么,所以如果有人要做影响整个系统的事情,那应该是你。

然而,如果你更深入地思考这一点,你会发现这种非干扰性原则也意味着你需要实施防护措施。例如,如果你是AWS,一个客户不应该能够请求数据中心里如此多的资源,以至于突然之间没有其他客户可以运行他们的关键工作负载。如果你是一个部署系统,一个客户不应该能够给你的系统施加如此大的负载,以至于破坏其他人的部署。构建这些防护措施通常是构建平台的大部分工作。 你必须仔细考虑“一个客户如何可能破坏另一个客户”,并设计系统使这不可能发生。

系统的可推理性 扼杀平台的最常见方法之一,就是使平台所有者难以或无法随着时间的推移演进平台。

每当你向客户提供一些自由时,问问自己这个问题:“如果我们改变对这个功能如何工作,或者核心产品如何工作的想法,会发生什么?” 你是否能够仅凭平台团队自己以安全、自动化的方式进行更改,还是你必须要求所有客户进行手动工作?更重要的是,你将来如何知道一个更改是否安全?你是否必须四处走动,与每个客户交谈,询问他们“你们是如何使用平台的?”以及“我想做的这个更改对你们安全吗?”还是存在某种以编程方式分析你所有客户的方法,使你完全了解客户如何使用你的产品以及可以进行哪些更改?

本质上: 无论客户做什么,你必须继续能够推理你的系统行为。 需要能够轻松地进行逻辑陈述,例如:“如果我们为所有人更改将代码推送到服务器上的工具,我知道这是安全的,无需询问我们的客户,因为 ______________。”

如果你允许客户太多的自由,你将违反这一原则。例如,假设你正在设计一个平台,它获取客户的代码,将其构建成二进制文件,并运行其测试(基本上是一个持续集成系统)。如果你让每个客户编写完全不同的构建脚本,可以做他们想做的任何事情,那会怎样?你就不再是一个持续集成系统,而变成了一个完全通用的任务编排器。你不再能为客户提供任何特定于持续集成的价值。你甚至无法再在安全与价值之间进行权衡推理(例如“我们是否应该让这些脚本访问互联网?”)。它甚至“感染”了你系统的测试部分,因为系统的测试部分不知道它得到的是什么——它可能是任何脚本的任何输出。于是测试系统也变成了一个通用的任务编排器。如果你想要的只是这些,你本可以直接使用众多开源任务编排器中的一个,从一开始就为你的客户提供很少的价值。

一旦陷入这种境地,就很难摆脱。想象一下,你想从那种状态转变为拥有一个更受限制、更标准化的构建系统。整个公司有数百或数千个不同的构建脚本,现在你必须要么自己去手动查看所有这些脚本,要么要求所有客户去“修复”他们的脚本(祝你好运)。这引出了你在长期从事这类平台工作后学到的另一件事: 从自由走向限制远比从限制走向自由要困难得多。

本质上,你永远不希望给人们一些东西然后又不得不拿走。你总是希望“给予”他们一些你永远不需要收回的东西。当我说“从自由到限制”的道路要困难得多时,我的意思是需要付出几个数量级的努力——有时甚至到了不可能的程度,你只能放弃再次控制平台那部分的任何希望。(这就是导致平台所有者创建向后不兼容的“2.0版”平台的原因,他们放弃了所有现有客户,但这又带来了全新的、可怕的问题!)

总的来说,你绝不允许给予客户如此多的自由,以至于你无法再推理系统的行为,从而无法再有效地演进或增强它。

逃生舱口

你可能听说过平台的“80/20法则”。这意味着核心产品功能应以真正简单和出色的方式,成功处理80%的用例。然后,那20%具有非常独特需求的客户在平台中获得更多权力,能够满足他们更复杂的需求,即使这意味着他们的用户体验更复杂。

很多时候真正发生的是:那20%的用户拥有很大的权力。通常,最大和最重要的客户系统就在那20%的用户中。他们出现并要求完全的自由,你会陷入一种无法再推理或维护你的平台的境地。

所有平台都需要牢记这个原则: 必须有某种方式让客户满足他们合法的需求。 你的客户有真实的需求,他们需要能够执行这些需求。他们并不生活在你在脑海中为你的平台设计的、神奇的围墙花园里。总会有一些客户的需求远远超出你系统打算支持的范围。

然而,我要强调这一点:那些客户满足其需求的方式不一定非得是你的平台。只需要有某种方式让他们能够满足需求即可。

所有平台都需要“逃生舱口”,允许有限的一组客户做他们需要做的任何事情。但是,维护和支持的负担必须落在这些客户身上。平台所有者必须尽可能与支持这些客户的成本隔离开。

通常,你实现这一点的方式是拥有两个层面:

  1. 一套让人们可以做他们需要做的任何事情的工具。对于开发者平台,这些通常是具有复杂界面和巨大功能的命令行工具。
  2. 一个建立在这些工具之上的**“平台”**,它创造了出色的用户体验,但相对于工具而言,极大地限制了系统的能力。这解决了80%或更多的常见用例,但要求客户遵循特定的、标准化的工作方式才能获得好处。我们通常称之为“铺平的道路”或“黄金路径”。这有点像高速公路——它不通往所有地方,但它通往大多数人想去的地方,而且方式比走小路更加顺畅。

你的绝大多数用户应该使用这个平台。对于那些不使用平台的用户,你需要一个地方来记录哪些客户因其复杂需求而采取了“逃生舱口”并被允许使用底层工具。未来会有很多人想知道那些团队是谁,比如你的安全团队(“我需要一份使用逃生舱口的所有人的名单,因为我们为一个使用平台的每个人集中修复了一个漏洞,但所有使用逃生舱口的用户都需要自行修复。”)。

如果你没有这些逃生舱口,你就无法对任何客户说“不”。 你必须能够对不应该在平台中出现的功能说“不”。否则,你的平台将随着时间的推移而退化——有时甚至到了如果你一开始就没有这个平台会更好的地步。当你必须“对所有人提供一切”时,你的产品可能变得如此复杂,以至于实际上拖慢了客户的速度,而不是加快他们的速度。

不过,有一件事需要注意:当你的很多用户开始使用逃生舱口而不是平台时。 这表明可能有几种不同的情况发生:

  1. 很多团队有合法的需求,而你没有在平台上成功实现。
  2. 企业中没有激励措施促使团队使用平台,因此他们“走捷径”(使用逃生舱口),这对他们来说当下努力较少,尽管从长远来看对他们来说成本更高。

几乎总是你的平台存在问题。永远不要过于自信地认为你已经做好了一切,没有东西可学了。即使问题看起来在于激励机制(人们觉得迁移到你的平台不会得到个人奖励,领导者觉得这项工作不重要等),真正的问题往往是:接入平台太困难了。

人们根据他们拥有的数据和他们试图实现的目的来做决定。如果他们关于你的平台的数据是“如果我使用那个平台,将很难实现我的目的”,那么你将很难让人们采用它。

什么是合法的需求?

上面我经常谈论“合法的需求”或“有效需求”。这些是什么? 一个合法的需求是对公司整体最有利的事情,并且源于客户真实存在的问题。

作为平台所有者,我通常还会说这里有一个时间线的方面:从长远来看正确的需求,而不仅仅是从短期来看正确的需求,才是更合法的。偶尔会有非常令人信服的理由为短期妥协,但如果你这样做,要思考如何最终朝着正确的长期解决方案努力。

即使你正在为单个客户构建第一个产品时,这一点也是正确的。我不是说要猜测未来。不要担心“我是否为所有其他可能的未来客户以最佳方式实现了这个产品功能?”这条路会导致臃肿、糟糕的产品。相反,只需问:“我为这个客户所做的是否能为企业带来最好的结果?”

后来,当你构建一个平台时,仍然是同样的问题:“这个客户想做的事情是否对公司整体来说是正确的?”例如,假设你是一个所有东西都用Java编写的公司。一个客户来找你说:“我打算用Python构建这个系统,所以我需要你支持Python系统。”嗯,这可能是合法的。让我们了解更多:为什么他们想使用Python?“哦,我只是更喜欢它。”所以这个客户想基于个人偏好打破公司的标准。这不是一个合法的需求。

另一方面,假设同一个客户对同一个问题有不同的回答:“我们正在构建一个机器学习系统,而Python是整个行业机器学习系统的标准语言。我们在Python中可用的工具对这个产品的成功有巨大影响。”这听起来是一个非常合法的需求。而且,我们刚刚学到了更多——客户想要部署一个机器学习系统,这实际上会带来一整套额外的需求。

作为平台所有者,你必须拒绝实现那些对公司整体不正确的要求。 这些要求不仅给公司带来麻烦,还倾向于随着时间的推移降低平台的质量。它们添加了大多数客户并不真正需要的“累赘”,以提供公司并不真正需要的功能。

无效的需求

当你深入探究时,会发现有多少平台需求实际上并不合法,这非常令人惊讶。常见的一种是:“如果你做大量的工作来节省我们一点点工作,这对我们来说会更方便一些。”有时客户甚至没有考虑将其系统迁移到你的平台上需要多少工作。他们很忙,甚至不愿意考虑做更多的工作。他们可能只需要几个小时的工作来修复他们的系统,使其更标准化,但他们感到不知所措,甚至没有做出这个估算。

如果你有1000个客户,你花费20小时的工作能为每个客户节省1小时,这听起来是一个你绝对应该做的伟大权衡!但如果你花费20小时的工作只为节省一个客户的10小时工作,这显然不是对公司整体正确的决定,所以不要做。

另一个常见的问题是想象出来的需求。客户有时相信他们有但实际上并不具备的需求。一个客户来说:“这必须扩展到每秒一百万次查询。”你问他们为什么,他们说:“因为我们的产品经理这么说。”你问产品经理,他们说:“我只是想确保系统的能力远超我们的需求,以防我们扩张得比预期的快一点。”当你让人们做真正的计算时,你会发现,即使我们在使用量方面超出了我们最疯狂的梦想,系统实际上也只会处理每秒一千次查询。

所以你需要确保客户的需求基于他们需要解决的实际问题的现实。礼貌地处理——不要说他们是想象出来的。只是要求澄清,以便你尽可能充分地理解需求。通常,即使这是一个合法的需求,你也会通过这样做发现更多相关信息。例如,如果那确实是一个每秒服务一百万次查询的合法需求,你会学到很多东西,比如:我们必须以什么延迟服务这些查询?我们必须将这个系统托管在多少个不同的区域?流量是否在一天中的特定时间达到高峰?等等。

要接受的最危险的需求类型之一是“请为我们构建这个解决方案”。例如,假设你构建了一个安全平台,使用不同的工具扫描代码以查找漏洞,但你追求的结果是成功找到漏洞,而不仅仅是“运行工具”。一个客户来找你说:“请开始运行这个名为QuxBugs的新供应商工具。”你的回答应该是:“哦,谢谢你的请求。你能告诉我更多关于你试图解决的问题吗?”永远不要接受平台客户提出的解决方案,只接受他们试图解决的问题的描述。在极少数情况下,他们提出的解决方案可能是正确的,但大多数时候并不是。不幸的是,即使你将那个解决方案交付给他们,他们最终也会讨厌它,因为那是错误的解决方案。

大多数工程师并不擅长详细说明他们的需求。你必须帮助他们。通常,当你有一个合法需求时,解决方案会变得显而易见(至少对你,平台所有者来说)。即使解决方案没有完全变得显而易见,拥有正确的需求也为找出正确的解决方案打开了大门,并有助于澄清你在开发解决方案时出现的任何问题的答案。一般来说,如果你不确定如何实现某件事,可能你对这个问题还没有完全理解。

平台的挑战

以上阐述了我所知道的关于如何设计和开发用户喜爱的卓越平台的基本原则。做这些事情面临的挑战大多是组织和社交方面的挑战:改变人们的想法,让领导者认同“以正确的方式行事”,获得开发产品以及最终平台所需的资金和时间等。所有这些都是非常现实的问题,但至少,如果你理解并应用上述原则和流程,你将知道应该如何达到目的地。我希望你这样做,并体验到实现、运营和维护一个真正卓越平台的快乐。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计