作者|KislayVerma翻译|崔浩评论|越来越普遍。系统理论告诉我们,系统中相互关联的部分越多,它就越有可能失败。因此,要构建弹性系统,我们需要减少这种互连。否则,需要“暂时”切断与故障点的连接,避免问题的发生,保证其他节点的正常运行不会受到故障点的影响。也就是我们通常所说的分布式系统的降级融合。Diagram组件之间的关系一般基于以下假设:分布式系统中的任何组件都可能随时发生故障,需要定义发生故障时相应的处理方法。最后,我们需要在系统中创建缓冲区——在无法完全消除对故障组件的依赖时,提供一些宽松的方式来以更温和的方式处理意外情况。PART02最小化组件之间的依赖性。分布式系统的组件通过相互通信获取数据和调用功能。在这两种情况下,可以通过将数据/功能推送到调用组件而不是通过远程访问获取它来减少组件之间的连接需求。构建大型分布式系统迫使我们放弃标准软件工程的许多“最佳实践”。重点在于,在用分布式系统的复杂性换取系统的可扩展性时,需要尽可能地控制组件的“分布”。需要注意以下几点:1.复制数据如果您经常访问组件中的某些数据,则可以复制该组件而无需在运行时检索它。这种方式可以大大降低对组件的依赖,降低访问组件的延迟。对于频繁访问和定期更改的数据,可以通过临时缓存和定期缓存刷新来获取。更改频率较低或从不更改的数据(例如客户姓名)可以直接存储在组件中。但是,当数据发生变化时,需要做一些额外的工作来更新它,但是这个小小的开销对于整个系统来说是值得的,因为它提高了系统的弹性。2.非规范化数据非规范化数据以特殊形式作为副本存在于组件中。如果使用关系数据存储数据,则可以通过复制主实体中的数据来降低查看多个实体的成本。它还适用于定位分散的数据以获得更好的性能。3.组件库为了减少组件的功能依赖,可以将远程组件打包成一个组件库,嵌入到需要调用该库的组件中。这种做法并不总是可行的(存在跨语言调用,或者因为组件太大无法打包成一个库),所以会带来一系列的问题(例如:多个组件库由于某个功能,一次功能变化需要升级多个组件库)。话虽如此,如果功能很关键,访问频率很高,组件库方法可以减少组件之间的联系,让依赖的组件库成为调用组件的本地方法。隔离错误隔离错误的能力很重要,原因有二。一是分布式系统中个别错误非常突出。(具有许多活动部件的简单功能)。二是如果不能防止错误级联影响整个系统,就不可能构建复杂的系统架构。错误隔离由SLA(ServiceLevelAgreement服务保证协议)组成。它声明了每个组件的质量参数,这些参数在组件执行过程时被引用。质量参数包括:延迟、错误率、并发等。组件调用组件进行SLA设置时,调用者会根据被调用方的SLA参数进行设置,目的是在调用时采取相应的措施失败。比如调用方发现被叫方的错误率已经达到70%,就会延迟调用该组件5秒。如果被调用者的组件检测到它无法维护自己的SLA,它可以先发制人地告诉其调用者退出并稍后再回来。也就是,一旦被叫方身体不适,就告诉来电方你稍后会来访。同时,为了维护整个系统的健康,最好使用fastfail方式通知调用者,而不是在SLA被违反时让调用者成功。需要注意的是,调用者和被调用者都必须进行此设置。保护调用者不超时:如果被调用的组件在其SLA设置的范围内没有响应,调用者必须设置相应的超时机制,或者放弃或使用fallback机制(即使抛出错误),从而维护自己的SLA并防止发生一连串的SLA违规行为。重试:网络的不可靠性会导致分布式系统出现随机错误。如果调用者自己的SLA设置允许,则假定允许重试操作。重试操作的前提是被调用方需要支持操作的幂等性。即无论执行多少次改变数据状态的操作,都只计一次。断路器:如果呼叫连续失败,呼叫者可以“打开电路”切断连接并停止呼叫一段时间。由于调用者有针对错误场景的备份计划,它为调用者节省了宝贵的资源,否则这些资源将被浪费。停止调用还可以减少被调用组件的负载,为其提供喘息的空间。“断路器库”定期轮询有问题的组件,并在有可能恢复性能时重新启动调用机制。保护被调用者免受随机补偿:重试虽然可以降低调用错误的概率,但是对于被频繁调用的组件,小的性能问题都会导致调用者重试。当调用者足够多时,就会形成“重试风暴”,结果会出现不利于被调用者恢复的负载高峰。为防止这种情况发生,应设置随机重试间隔以错开重试负载。背压:如果一个组件检测到它承受的负载太大并且即将违反其SLA,它可以先发制人地开始丢弃新请求,直到它的性能得到控制。这比接受它知道无法在SLA范围内交付或冒着完全崩溃的风险的请求要好得多。在系统中建立缓冲区1.异步通信可以通过消息总线等异步通信方式调用远程组件,不需要非常严格的SLA参数规则。消息总线存储访问被调用方的请求,被调用组件准备好后处理这些请求,而不是立即处理请求,这样系统可以更灵活地处理负载。2.弹性供应可扩展性也可以通过利用硬件扩展来实现。如果系统规模不断增长,就需要分配更多的硬件资源来满足系统的需求。虽然这种类型的扩展需要具有成本效益并且在我们力所能及的范围内,但它也提供了针对不可预测负载的最后一道防线。原文链接:https://kislayverma.com/software-architecture/building-robust-distributed-systems/译者介绍崔浩,51CTO社区编辑,高级架构师,18年软件开发和架构经验,10年经验在分布式架构中。他曾经是惠普的技术专家。乐于分享,撰写了多篇阅读量超过60万的热门技术文章。《分布式架构原理与实践》作者。
