写点什么

边界:构建可靠系统的一些考虑点

2017 年 1 月 02 日

复杂的系统一般是由很多离散的部件组成,这些部件会出现故障,而且有时候会有多个部件同时出现故障,所以复杂的系统通常是运行在故障模式下。在一个采用了微服务架构的系统里,一个功能可能需要调用多个服务,因此每个部件的可用性决定了整个系统的可用性。这是弹性工程背后的核心逻辑。假设一个功能依赖三个服务,每个服务分别具有 90%、95% 和 99% 的可靠性,那么部分可用性就介于 99.995% 和 84% 之间(假设失效是单独发生的)。弹性工程意味着在设计时要把失效作为常规的考虑因素。

预测失效是弹性工程的第一步,而第二步是拥抱它们。告诉客户,可预知的失效好过未知或非期望的失效。回压是另一种弹性模式。从根本上说,回压就是要对资源强加限制。比如队列长度限制、带宽限制、流量控制、消息速度限制、消息大小限制等等。如果不显式地进行限制,它们就会变成隐式的(比如服务器的内存会被耗尽,不过因为这种限制是隐式的,所以无法准确地预测在什么时候会发生什么问题)。使用无边界的队列或其它一些隐式的限制就好比有人声称知道自己什么时候可以戒掉酒瘾,因为人总有一死,或许到了那个时候就不会再喝酒了。

速率限定不仅能够防止那些糟糕的 actor 破坏你的系统,它同时也是为了防止你自己对系统造成破坏。队列限制和消息大小限制是最有趣的,因为它们让很多开发者感到疑惑,同时也让他们感到沮丧,因为他们还没有完全搞清楚它们背后的动机。它们其实也是速率限定的另一个形式,或者说回压。下面我们拿消息大小限制作为例子。

假设我们有一个分布式系统,系统里的 actor 可以给其它 actor 发送消息,接收消息的 actor 对收到的消息进行处理,当然它们也可能往外发送消息。好的软件工程师都知道,分布式计算的第八个谬论是“均等网络”。所以,并不是所有的 actor 都使用相同的硬件、软件或者网络。我们有运行 Ubuntu 的拥有 128G 内存的服务器,有运行 macOS 的拥有 16G 内存的笔记本电脑,有运行 Android 的拥有 2G 内存的移动客户端,还有 512M 内存的物联网设备,在这些设备上面运行着各种各样的软件和网络接口。

如果我们不对消息的大小进行限制,那么我们就是在制造隐式的限制(上面我们对此做过讨论)。换句话说,你和你的交互方正在遵循一种无言的协议,双方都无法请求退出。因为任何一个 actor 都可以发送任意大小的消息,那么下游的消费者必须直接或者间接地支持任意大小的消息。我们怎么可能对任意大小的东西进行测试呢?我们做不到。我们只有两种选择:要么做出显式的限制,要么保持这种隐式的限制。如果选择了前者,我们可以定义我们的行为边界,并且对其进行测试。而后者要求我们基于未定义的生产规模进行测试,这是在拿系统可靠性作为赌注。第二种情况的限制依然存在,只不过被隐藏了起来。如果我们不让它们变成显式的,很容易在生产环境受到 DoS 攻击。在云基础设施环境中,因为它们的多租户特性,这些限制变得尤为重要。这些限制可以防止糟糕的 actor(包括你自己)拖垮服务,或者垄断基础设施和系统资源。

在我们的异构 actor 系统里,我们针对移动设备和 Web 浏览器进行消息限制,它们一般都是单线程或内存受限的消费者。如果没有显式的消息大小限制,客户端可能会因为请求过多的数据或接收无法处理的数据而崩溃,这就是为什么有些协议虽然没有明确规定但必须存在。

让我们从企业的角度来看待这些问题。假设有另一个系统:美国国家高速公路系统。美国交通局通过 Federal Bridge Gross Weight Formula 来防止大量的汽车对道路和桥梁造成破坏。这里存在着相同的工程问题,只不过规则和基础设施不太一样。

2007 年 8 月,明尼阿波里斯市的洲际 35W 密西西比河大桥坍塌,这个事故引起了人们对于卡车重量和大桥承受力之间关系的思考。2008 年 11 月,美国国家交通安全局给出大桥坍塌的几个原因:有缺陷的加固板、不精确的勘察、过重的建材以及高峰时期的车流重量。

交通局依赖地磅来确保卡车重量与官方允许的重量合规,并对超重的车辆进行处罚。

官方规定的最大重量是 80000 磅。超过这个重量的卡车依然可以在高速上行驶,不过行程会受到限制。超重许可只会被发放给那些无法拆分至符合官方标准的货物,而且除了卡车以外没有其他方式可以运载这些货物。

重量限制需要被硬性规定,这样工程师们在建造道路、桥梁和其它基础设施时就有章可循。计算机系统也一样。这也就是为什么很多计算机系统硬性规定了很多限制。例如,Amazon 就对他们的 Simple Queue Service 做了明确的限制——标准队列最多可承载 12 万个不落地的消息,而 FIFO 队列是 2 万个,而且消息大小被限制在 256K 以内。Amazon Kinesis、Apache Kafka、NATS 和 Google App Engine 所使用的消息都限制在 1M 以内。系统设计者可以通过这些限制来优化他们的基础设施,并降低多租户环境存在的风险——虽然置之不理会让资源计划变得更简单。

不管是队列、消息大小、查询或者流量,不对它们进行限制是一种弹性工程反模式。不对它们进行显式地限制,故障会以不可预期和非期望的方式发生。要记住,限制其实是时刻存在的,只是有时候它们被隐藏起来了。通过显式的限制,可以让故障的发生更加地可预期,而且发生故障的平均时间变长,而从故障中恢复的时间变短,只要在事先多做一些稍微复杂一点的工作。

事先做出显式的限制,好过让系统在不可预期的情况下发生故障。后者虽然在前期会少作一些工作,但从长期来看会带来更多的问题。要求开发者们直接做出显式的限制,他们会因此认真思考他们的 API 和业务逻辑,并设计出稳定、可伸缩、高性能的交互系统。

查看英文原文: Take It to the Limit: Considerations for Building Reliable Systems


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注 我们。

2017 年 1 月 02 日 18:001236
用户头像

发布了 321 篇内容, 共 111.8 次阅读, 收获喜欢 113 次。

关注

评论

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

由两个问题引发的对GaussDB(DWS)负载均衡的思考

华为云开发者社区

数据库 数据 负载

每天花2小时复习阿里P9分享的Java面试指南,高级架构教程,你也可以进阿里!

Java成神之路

Java 程序员 架构 面试 编程语言

京东城市时空数据引擎JUST亮相中国数据库技术大会(附PPT链接)

京东科技开发者

数据库 nosql

架构师训练营第六周作业

Geek_xq

太平金科助力“开局之战”顺利启动,博睿数据“A+N”一体化解决方案全力护航

博睿数据

APM npm AIOPS

博睿数据支持腾讯云函数监控,Serverless时代已来临

博睿数据

Serverless APM 监控

硕二面试阿里被吊打,不甘!复盘狂啃底层技术,拿下阿里P6+offer

Java成神之路

Java 程序员 架构 面试 编程语言

震精!京东T8大牛每天熬夜到凌晨三四点,竟然是在写Docker教程

Java成神之路

Java 程序员 架构 面试 编程语言

即构低延迟直播产品L3,打造更优质的实时互动体验

ZEGO即构

架构师训练营第六周总结

Geek_xq

【得物技术】交易轨迹系统

得物技术

数据 交易 得物 得物技术 自定义

网易有道 iOS二面经验分享

iOSer

ios 面试题 网易 大厂面试 iOS面试

看完这篇,保证让你真正明白:分布式系统的CAP理论、CAP如何三选二

四猿外

架构 分布式系统 CAP CAP原理 CAP理论

接口测试-使用mock生产随机数据

测试人生路

接口测试

面试字节跳动定级2-2,拿32*16offer,P8大佬的算法教程给了我春天!

Java成神之路

Java 程序员 架构 面试 编程语言

阿里P9在Github上分享的Java面试突击手册,凭借它,我拿下了阿里P7的offer!

Java成神之路

Java 程序员 架构 面试 编程语言

AI技术在音视频领域的发展

anyRTC开发者

人工智能 ios android AI WebRTC

公安大数据可视化指挥决策平台建设,智慧警务系统开发

WX13823153201

京东将上线社区团购“京喜拼拼”:社区团购是否是一次泡沫大战

石头IT视角

测开之函数进阶· 第5篇《偏函数》

清菡

测试开发

七大步骤,详解预置算法构建模型的全过程

华为云开发者社区

架构 算法 数据

推陈出新,一步到位,智慧水务这么用效率翻倍

一只数据鲸鱼

物联网 数据采集 智慧城市 组态软件 智慧水务

咨询师的诱惑

escray

面经 大龄程序员 面试经历 101次面试

数字资产钱包系统开发及介绍

系统开发咨询:I76-883I-5I52 邓森

年前成功拿下35K+16薪美团Java架构师Offer!考点、面试题分享送给明年金三银四的你

Java架构追梦

Java 架构 面试 美团 offer

轮子虽好,也要知其所以然!(Lombok操作实例)

程序员小毕

Java 源码 架构 开发工具 lombok

ONES 年终报告 | 功能升级123次,服务超100万客户

万事ONES

研发管理工具 年终报告

花火交易所APP开发|花火交易所软件系统开发

开發I852946OIIO

系统开发

LeetCode题解:剑指 Offer 40. 最小的k个数,二叉堆,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

互联网寒冬下,程序员如何化解危机?答案全在这份阿里Java知识地图里

比伯

Java 编程 程序员 面试 计算机

大数据ETL批量调度,这几款工具都需要去掌握了解

会飞的鱼

大数据处理 kettle 运维自动化 海豚调度 ETL算法

边界:构建可靠系统的一些考虑点-InfoQ