写点什么

我们应该如何构建复杂系统

  • 2015-05-07
  • 本文字数:4006 字

    阅读完需:约 13 分钟

Mary Poppendieck 工艺大会新新软件开发运动:容器、微服务”中做了一次非常精彩的演讲,她说,我们必须能够更好地完成复杂的软件系统。

洞察力推动着复杂度随规模呈非线性的增长。其实这和系统的类型无关,我们很清楚软件规模将持续不断地增长,所以软件复杂度将更加快速地增长。

我们可以如何应对?以下主题可以减少阻滞并降低风险:

  • 更低的阻滞。这可以让你更加迅速地响应变更。可采用的方法有:抛弃集中型数据库、采用微服务、使用容器、把团队更好地组织起来。
  • 限制风险。复杂的系统里必然会有风险。可采用的方法有:契约测试、持续交付等。

一些关键点:

  • 软件什么时候会得到真正的发展?当聪明的人们可以干着自己的事情,而不必考虑对其他人的影响时,软件就发展了。建议构建联邦系统 以确保独立性(注:各系统间彼此独立,无硬性依赖,可针对特定目标予以联合使用。),建议采用微服务和容器。
  • 通常可以从单系统成功地进化出微服务。在创建一个单系统的过程中,开发人员就知道如何适当地划分系统了。
  • 阻滞更低且风险更小的持续交付。在复杂系统中如果你想要稳定性、如果你想要安全性、如果你想要可靠性、如果你想要保密性,那么你就必须要进行很多次小的部署。
  • 每个团队成员清楚每一件事。什么会建设出一支成功的团队?那就是好的势态感知能力。

Mary 在国内为大家带来了精彩的演讲,我觉得,演讲的亮点是瑞典喷气式战斗机“狮鹫”的绝妙设计。她谈到了微服务趋向于高度的抽象,谈到了构建中的软件乐趣,谈到了零件可以如此地笼统、抽象。具有多个系统的喷气式狮鹫联邦设计非常地务实和实用。它可以让你在更换枪炮、雷达系统时不必考虑对其他部分的影响,事实上更换任何组件都不必有此顾虑,这是多么的神奇呀!这些只是 Mary 本次演讲的部分内容,大家千万不要错过呀!这是一个非常丰富而细腻的演讲,给出了许多的历史背景,所以我无法记述其中的所有细节,演讲视频还是很值得一看的。就先说这么多吧,欢迎大家观看本次演讲的视频以亲自感受更多的精彩内容。

通过抽象化和小型化进行硬件的扩展

软件只不过发展了 40 个年头,但硬件已经走过了很长的一段路:中央处理器、算法、接口等已经抽象成了一个单独的芯片,这些芯片的体积已经非常的小了。芯片焊接到电路板上,电路板附加在主板上,主板也经过了抽象和简化。主板是一组插槽,每个插槽就是某类抽象。比如平台,有内存、CPU 等等。你可以在每个插槽上插上点什么。比如,你可以把任何兼容的内存插到内存插槽中。反复不断地重复这个过程。但是,软件不能像硬件这么扩展。

通过联邦和广泛参与进行软件扩展

软件什么时候会得到真正的发展?当聪明的人们可以干着自己的事情,而不必考虑对其他人的影响时,软件就发展了。我们已经见识到了 Web 的发展模式和云的发展模式。1989 年,Tim Berners-Lee 提出了超链接的思想,后来在 1993 年诞生了全球第一款网页浏览器 Mosaic。出乎意料的是,全世界发生了软件大爆炸。Web 发展的原因是,每个节点都可以做它们自己的处理,它们与其他每个节点完全都是联邦的关系。每个节点可以做它们自己的事,不必在意其他的节点。节点间是彼此隔离的,一个节点做什么都不会对其他的节点产生任何的影响。云重复了这个模式。我们又一次看到了软件大爆炸,这次是和云在一起。无论是个人、团队,还是公司,都可以在云中创建属于自己的环境,你可以在这个环境中做自己的事,不会对其他人造成任何影响。过去,我们就是这么扩展软件的,将来,我们仍然可以这样扩展软件。

集中式数据库增加了阻滞,导致了单系统架构的失败

集中式数据库成为一种厚重的、紧耦合的机制。在系统中干什么都要加锁,因为每个组件都必须用数据库来管理状态。如果我们需要做到像互联网那样的解耦,使每件事彼此间都互不相关,那么就不会让数据库成为系统的限制。集中式数据库是一种高阻滞的架构。

微服务通过降低阻滞取得成功

微服务把数据库作为一个耦合的设备给移除了。这是一个大胆而违反常规的思想,让每个服务都有它自己的数据库。微服务让每个团队和个人都可以去进行他们想要的变更。降低阻滞可以更加快速地响应变更。一个微服务只做一件事。这是一种联邦的架构,一个微服务就是一个独立的部署单元,只要不违反服务契约,该服务就可以独立于任何其他的服务予以部署。一个微服务由一个小团队来完成,这个团队需要具备服务构建、部署和管理所需的所有技能。团队为该服务提供端到端的响应。

实践:没有集中式数据库;大量的自动化和监控;消费者驱动契约测试;灵活的服务版本控制;金丝雀发布(canary releasing)。

微服务增加的风险

虽然微服务肯定可以降低阻滞,却也增加了错综复杂的串接和不良划分的风险。服务之间很有可能会形成地狱般错综复杂的串接。对象承诺会带来很多好处,这些好处与微服务大致相同。但最终对象间会产生千丝万缕的联系,这些好处也就不复存在了。

缓解微服务的串接风险:

  • 有边界的上下文。每个微服务都应该对应到真实世界中的某件事物。这是自然而然的事。
  • 集成服务自己要确保其下层服务的行为。
  • 纪律。服务必须通过接口来提供,不要用其他的途径。
  • 变更意识。团队必须要密切关注任何变更的影响。

通常可以从单系统成功地进化出微服务。只有当他们真正地理解了所属的领域,才能够切换到微服务。在单系统中很容易重构,但在微服务里却很难做到。如果你的结构不适当,就真的很难去重构。具有很多成功的案例的公司都是从单系统开始着手的,因为他们了解所属的领域,能够对微服务如何进行划分做出良好的决策。

瑞典狮鹫喷气式战斗机多系统联邦设计示例

瑞典狮鹫喷气式战斗机的设计如同一个令人着迷的故事,故事讲述了一个梦幻般的系统工程,它创建的架构完全适用于成本低廉的开发。瑞典把喷气机停放在一片洼地之中,这片洼地隐藏在一片树林之中。它们的降落跑道只有半公里那么长。一队士兵和一名工程师会随时待命,在30 分钟内为它们提供服务。持续地降低操控成本是狮鹫一直以来的主要目的。狮鹫每小时的操控成本为4700 美元,而F35 却高达31000 美元。新出的每一代狮鹫都会有更低的操控成本。

设计目标:高可靠性、低成本、灵活的执行效率。

他们设想的是狮鹫联邦架构就像智能手机架构。它有一个航空平台和一堆的应用,比如环境控制系统、水力学系统、供电系统等等。许多人已经建好了雷达系统和机枪系统。如果你的架构合理,那么就可以直接购买这些系统了。在真正的联邦架构中,换个机枪是不会对系统的其他部分产生什么影响的。即使这是个安全关键系统,有一大堆的航空管理条例,但他们仍然能够把它设计成了真正隔离的平台,所以更任何一个主要子系统都不用担心对航空系统产生不良的影响。任何国家的任何组件都可以单独接入,航空平台不必进行重新认证。狮鹫航空平台的开发速度非常迅速,并具有独立的联邦组件,它的主版本升级频率与安卓平台大致相同。

因为重量的限制,他们不能让每个组件都拥有一台独立的计算机,他们的做法是在一台独立的计算机里建了一个稳固的容器,确保容器中的系统彼此之间不会产生影响,谁也不能够耗尽容器中的所有资源。他们拥有一个联邦的架构,该架构使他们可以遵守重量的限制,组件可以接受同一台硬件的控制。

容器减少的是阻滞,而不是风险。

阻滞会让事情变慢。容器减少阻滞。在上船之前,码头工人会把每件产品打包成集装箱。在70 年代之后,变成了集装箱式货运。如今已减少了大量的阻滞,它创造了一次经济革命。软件容器也可以降低阻滞。由于始终保持一致的环境,所以构建出来的产品可以在任何地方运行。联邦可以让不同的系统之间互相独立。它们也增加了服务器的利用率并降低了成本。容器不是用来限制风险的。

持续交付减少阻滞和风险

你怎么知道在五分钟前部署的微服务会不会有不良的影响呢?这不是个简单的问题。

端到端的测试解决不了这个问题,因为代码变得太快了。而且端到端的测试会让你丢失独立的部署机制,使速度变得很慢。目标是在不增加阻滞的情况下降低风险,但两者的关系却很微妙。我们决不想放弃服务,而是希望提升服务被正确部署的可能性。所以一个办法是在部署之前测试,验证其是否满足了契约。这些测试应该可以快速地运行,并快速给出反馈,对这些将要和已有服务一起工作的待部署代码予以评价。契约测试:由消费者驱动的契约测试,为消费者的项目提供mock 服务,为提供方的项目提供交互回调和验证。

现在的问题是,当你面对复杂的系统时无法进行测试,你也预想不到它将如何工作。对一个复杂系统做出重大变更时,你很难预先了解到它将会产生怎样的反应。不管你怎么努力地尝试,总会产生些意外的状况。

所以不要无谓地尝试了。攻击它吧。要想让大型复杂系统永远保持稳定,唯一方法就是不断地攻击它,看看它会做出怎样的反应。注意:此处所说的攻击的含义并不十分确定,很难把它界定得非常清楚。持续地测试?持续地部署? Netflix_ 风格的 _chaos monkeys?大家可以结合自己的实际情况予以定义。

有的人认为大量小部署具有危险性,这种想法是错误的。复杂系统就是需要进行多次小部署,这是个非常正常的思路。如果你想要稳定性、如果你想要保密性、如果你想要可靠性、如果你想要安全性,那么你就必须要进行多次小的部署。

任何大规模复杂系统都需要持续的部署。

组织

如何建设成功的团队?

  • 团队中的每个成员都要清楚每件事。拥有良好的态势感知。
  • 创建共同的目标,比如令客户满意。
  • 除非每个人都成功,否则谁都没有成功。
  • 通过监控让大家能够看清全局,从而建立态势感知。
  • 调节性匹配理论。有这么两类人,一类以危险为关注焦点,他们会提前预防失败,判断是不是安全的;另一类是以成功为关注焦点的,他们会创造财富,说干就干!一个团队同时需要这两类人,并维持彼此间的平衡。

感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-05-07 06:093124

评论

发布
暂无评论
发现更多内容

offer如何选择该考虑哪些因素

KEY.L

7月月更

Salesforce 容器化 ISV 场景下的软件供应链安全落地实践

阿里巴巴中间件

阿里云 容器 云原生 安全

算法入门很简单:算法题的破解之道上篇

宇宙之一粟

算法 7月月更

想要在Linux中只显示隐藏文件,用对ls就可以实现

wljslmz

Linux 运维 7月月更

当我们谈论不可变基础设施时,我们在谈论什么

阿里巴巴中间件

阿里云 容器 云原生 托管

全链路压测:影子库与影子表之争

阿里巴巴中间件

阿里云 云原生 全链路压测 影子

async / await

Jason199

Async await 7月月更

《HarmonyOS实战—入门到开发,浅析原子化服务》

攻城狮杰森

操作系统 HarmonyOS 7月月更

自律,提升自制力原来也有方法

沃德

程序员 7月月更

ServiceMesh主要解决的三大痛点

阿泽🧸

Service Mesh 7月月更

Ubuntu22.04 源码安装Python3.10

IT蜗壳-Tango

7月月更

Java 9 中的字符串(String)压缩的改进

HoneyMoose

Android 面试知识点

沃德

android 程序员 7月月更

组织实战攻防演练的5个阶段

穿过生命散发芬芳

攻防演练 7月月更

windows下设置TortoiseGit客户端连接git不用每次输入用户名和密码

乌龟哥哥

7月月更

leetcode 53. Maximum Subarray 最大子数组和(中等)

okokabcd

LeetCode 动态规划 数据结构与算法

当 Knative 遇见 WebAssembly

阿里巴巴中间件

阿里云 容器 云原生 Knative WebAssenbly

谈谈讲清楚这件事的重要性

阿里巴巴中间件

阿里云 技术 云原生

LinkedBlockingQueue源码分析-初始化

zarmnosaj

7月月更

Nginx 主机配置文件中如何配置能够支持 IPv4 和 IPv6

HoneyMoose

Linux 下的传统 IPC 通信原理

北洋

Andriod 7月月更

架构实战营模块 6 作业

Roy

架构实战营

牛客java选择题每日打卡Day8

京与旧铺

7月月更

鸿蒙智联汽车【1.0】

坚果

HarmonyOS OpenHarmony 7月月更

一个开发者自述:我是如何设计针对冷热读写场景的 RocketMQ 存储系统

阿里巴巴中间件

阿里云 RocketMQ 云原生编程挑战赛

AI人脸编辑让Lena微笑

逝缘~

华为云 AI Gallery 7月月更

抖音或将推出独立种草社区平台:会不会成为第二个小红书

石头IT视角

【愚公系列】2022年7月 Go教学课程 005-变量

愚公搬代码

7月月更

一个酷酷的“幽灵”控制台工具

为自己带盐

C# 控制台 7月月更

OpenSergo 即将发布 v1alpha1,丰富全链路异构架构的服务治理能力

阿里巴巴中间件

阿里云 微服务 云原生 云原生开源 OpenSergo

我们应该如何构建复杂系统_语言 & 开发_冬雨_InfoQ精选文章