improve format/punctuation

This commit is contained in:
Jerry Lee
2018-01-25 19:33:35 +08:00
parent 10a1ee15f3
commit 38d223f08a
2 changed files with 35 additions and 34 deletions

View File

@@ -2,21 +2,18 @@
在不同的领域深耕的各个组织都独立地发现了一种如出一辙的软件构建模式。这些系统更加的健壮、更加弹性、更加灵活并能够更好地满足现代化的需求。
这些变化方兴未艾,因为近几年应用程序需求已经发生了显著地变化。仅在几年以前,一个大型应用程序拥有数十台服务器、数秒的响应时间、数小时的维护时间以及GB级别的数据。而现在的应用程序被部署到了所有形态上,从移动设备到运行着数以千计的多核心处理器的云端集群。用户期望毫秒级的响应时间以及100%的正常运行时间。数据则是PB级别的。以前的软件架构已经根本无法满足现代化的需求了。
这些变化方兴未艾,因为近几年应用程序需求已经发生了显著地变化。仅在几年以前,一个大型应用程序拥有数十台服务器、数秒的响应时间、数小时的维护时间以及`GB`级别的数据。而现在的应用程序被部署到了所有形态上从移动设备到运行着数以千计的多核心处理器的云端集群。用户期望毫秒级的响应时间以及100%的正常运行时间。数据则是`PB`级别的。以前的软件架构已经根本无法满足现代化的需求了。
我们相信需要一种同调的系统架构方法,而且我们相信所有必要的方面都已经被独立地认识到了:我们需要具有即时响应性、弹性、适应性以及消息驱动的系统。我们称之为反应式系统。
被构建为反应式的系统更加的灵活、 松散耦合并是[可伸缩的](/glossary.zh-cn#可伸缩性)。这使得他们可以更加容易地被开发以及适应改变。他们对系统的[失败](/glossary.zh-cn#失败)更加地包容, 而当失败着实发生时, 他们将用优雅而不是灾难性的方式来应对。反应式系统具有极高的即时响应性, 给予[用户](/glossary.zh-cn#用户)有效的交互反馈。
被构建为反应式的系统更加的灵活、松散耦合并是[可伸缩的](glossary.md#可伸缩性)。这使得他们可以更加容易地被开发以及适应改变。他们对系统的[失败](glossary.md#失败)更加地包容,而当失败着实发生时,他们将用优雅而不是灾难性的方式来应对。反应式系统具有极高的即时响应性,给予[用户](glossary.md#用户)有效的交互反馈。
**反应式系统具有:**
* **即时响应性**:只要有可能,[系统](/glossary.zh-cn#系统)就会及时地做出响应。响应能力是可用性和实用性的基石,但是更加重要的是,响应能力意味着可以快速地检测到问题并且行之有效地解决它。即时响应的系统专注于提供快速而一致的响应时间,确立可靠的上界,从而提供一致地服务质量。这种一致的行为反过来简化了错误处理、建立了最终用户的信任、并鼓励他们进行进一步的交互。
* **性**:系统在出现[失败](glossary.zh-cn#失败)时依然保持即时响应性。这不仅适用于高可用的、任务关键型系统——任何不具备弹性的系统都将会在失败之后丢失即时响应性。弹性是通过[复制](/glossary.zh-cn#复制)、遏制、[隔离](/#glossary.zh-cn#隔离)以及[委派](/glossary.zh-cn#委派)来实现的。失败被包含在了每个[组件](/glossary.zh-cn#隔离)内部,和其他组件相互隔离,从而确保了系统的各个部分能够在不危及整个系统的情况下失败和恢复。每个组件的恢复都被委派给了另一个(外部的)组件,并在必要时通过复制来实现了高可用。(因此)组件的客户端(也就)没有了处理组件失败的负担
* **适应性**:系统在变化的工作负载之下依保持着即时响应性。反应式系统可以通过增加或者减少分配给服务于输入(负载的)资源,来响应输入(负载的)速率的变化。这意味着设计上并没有争用点和中心化的瓶颈,从而可以分片或者复制组件,并在他们之间分发输入(的负载)能力。通过提供相关的实时性能测量信息,反应式系统都支持预测式以及反应式伸缩算法。他们在日常的硬件以及软件平台上实现了成本高效的[适应性](/glossary.zh-cn#适应性)。
* **消息驱动**:反应式系统依赖[异步的](/glossary.zh-cn#异步的)[消息传递](/glossary.zh-cn#消息驱动)来确立组件之间的边界,以确保松散耦合、隔离以及[位置透明性](/glossary.zh-cn#位置透明性)。这一边界还提供了将[失败](/glossary.zh-cn#失败)作为消息委派出去的手段。使用显式的消息传递,通过在系统中形成并监视消息流队列,并在必要的时候应用[回压](/glossary.zh-cn#回压),从而实现了负载管理、适应性以及流控制。使用位置透明性的消息传递作为通信的手段,使得跨集群或者在单个主机中使用相同的构造和语义管理失败成为了可能。[非阻塞的](/glossary.zh-cn#非阻塞的)通信使得接收者可以只在活动的时候消耗[资源](/glossary.zh-cn#资源),从而带来更少的系统开销。
* **即时响应性**:只要有可能,[系统](glossary.md#系统)就会及时地做出响应。响应能力是可用性和实用性的基石,但是更加重要的是,响应能力意味着可以快速地检测到问题并且行之有效地解决它。即时响应的系统专注于提供快速而一致的响应时间,确立可靠的上界,从而提供一致地服务质量。这种一致的行为反过来简化了错误处理、建立了最终用户的信任、并鼓励他们进行进一步的交互。
* **弹性**:系统在出现[失败](glossary.md#失败)时依然保持即时响应性。这不仅适用于高可用的、任务关键型系统 —— 任何不具备弹性的系统都将会在失败之后丢失即时响应性。弹性是通过[复制](glossary.md#复制)、遏制、[隔离](/#glossary.md#隔离)以及[委派](glossary.md#委派)来实现的。失败被包含在了每个[组件](glossary.md#隔离)内部,和其他组件相互隔离,从而确保了系统的各个部分能够在不危及整个系统的情况下失败和恢复。每个组件的恢复都被委派给了另一个(外部的)组件,并在必要时通过复制来实现了高可用。(因此)组件的客户端(也就)没有了处理组件失败的负担。
* **适应性**:系统在变化的工作负载之下依保持即时响应性。反应式系统可以通过增加或者减少分配给服务于输入(负载的)资源,来响应输入(负载的)速率的变化。这意味着设计上并没有争用点和中心化的瓶颈,从而可以分片或者复制组件,并在他们之间分发输入(的负载)能力。通过提供相关的实时性能测量信息,反应式系统都支持预测式以及反应式伸缩算法。他们在日常的硬件以及软件平台上实现了成本高效的[适应性](glossary.md#适应性)
* **消息驱动**:反应式系统依赖[异步的](glossary.md#异步的)[消息传递](glossary.md#消息驱动)来确立组件之间的边界,以确保松散耦合、隔离以及[位置透明性](glossary.md#位置透明性)。这一边界还提供了将[失败](glossary.md#失败)作为消息委派出去的手段。使用显式的消息传递,通过在系统中形成并监视消息流队列,并在必要的时候应用[回压](glossary.md#回压),从而实现了负载管理、适应性以及流控制。使用位置透明性的消息传递作为通信的手段,使得跨集群或者在单个主机中使用相同的构造和语义管理失败成为了可能。[非阻塞的](glossary.md#非阻塞的)通信使得接收者可以只在活动的时候消耗[资源](glossary.md#资源),从而带来更少的系统开销。
大型系统是由较小的系统所构成的,因此依赖于他们的构成部分的反应式特性。这意味着,反应式系统应用了一些设计原则,因此这些属性也适用于所有级别的伸缩,使得他们可以组合。世界上最大型的系统都依赖于基于这些属性的架构,并每日服务于数十亿的人们的需求。现在是时候从一开始就有意识地应用这些设计原则,而不是每次都重新发现他们了。

View File

@@ -5,11 +5,11 @@
* [批量处理](#批量处理)
* [组件](#组件)
* [委派](#委派)
* [适应性(与可伸缩性对照)](#适应性)
* [失败(与错误对照)](#失败)
* [隔离(以及遏制](#隔离)
* [适应性(与可伸缩性对照)](#适应性)
* [失败(与错误对照)](#失败)
* [隔离(以及遏制](#隔离)
* [位置透明性](#位置透明性)
* [消息驱动(与事件驱动对照)](#消息驱动)
* [消息驱动(与事件驱动对照)](#消息驱动)
* [非阻塞](#非阻塞)
* [协议](#协议)
* [复制](#复制)
@@ -20,70 +20,74 @@
## 异步的
牛津词典把asynchronous异步的定义为*“不同时存在或发生的”*。在这个宣言的上下文中我们的意思是在来自客户端的请求被发送到了服务器之后对于该请求的处理可以发生这之后的任意时间点。对于发生在服务内部的执行过程客户端无法直接地观察到或者与之进行同步。这是同步处理synchronous processing的反义词同步处理意味着客户端只能在服务已经处理完成了该请求之后才能恢复他自己的执行。
牛津词典把`asynchronous`(异步的)定义为『_不同时存在或发生的_』。在这个宣言的上下文中,我们的意思是:在来自客户端的请求被发送到了服务器之后,对于该请求的处理可以发生这之后的任意时间点。对于发生在服务内部的执行过程,客户端无法直接地观察到,或者与之进行同步。这是同步处理(`synchronous processing`)的反义词,同步处理意味着客户端只能在服务已经处理完成了该请求之后,才能恢复他自己的执行。
## 回压
当某个[组件](#组件)正竭力地struggling跟上负载或者输入请求的速率整个[系统](#系统)就需要以合理地方式作出反应。对于该正在遭受压力的组件来说进行灾难性地失败或者不受控地丢弃消息都是不能接受的。因为他既不能成功地应对又不能直接地失败所以他需要向其上游组件传达其正在遭受压力的事实并让他们该组件的上游组件降低负载。这种回压back-pressure是一种重要的反馈机制使得系统得以优雅地响应负载而不是在负载下崩溃。回压可以一路级联到系统的用户在这时响应能力可能会打折但是这种机制将确保系统在负载之下的弹性并将提供可能允许系统本身通过利用其他资源来帮助分担负载的信息参见[适应性](#适应性)。
当某个[组件](#组件)正竭力地(`struggling`)跟上(负载或者输入请求的速率)时,整个[系统](#系统)就需要以合理地方式作出反应。对于该正在遭受压力的组件来说,进行灾难性地失败,或者不受控地丢弃消息,都是不能接受的。因为他既不能成功地应对,又不能(直接地)失败,所以他需要向其上游组件传达其正在遭受压力的事实,并让他们(该组件的上游组件)降低负载。这种回压(`back-pressure`)是一种重要的反馈机制,使得系统得以优雅地响应负载,而不是在负载下崩溃。回压可以一路级联到(系统的)用户,在这时响应能力可能会打折,但是这种机制将确保系统在负载之下的弹性,并将提供可能允许系统本身通过利用其他资源来帮助分担负载的信息,参见[适应性](#适应性)。
## 批量处理
当前的计算机为反复执行同一项任务而进行了优化:在CPU时钟频率保持不变的情况下指令缓存和分支预测增加了每秒钟内可以被处理的指令数。这就意味着将不同的任务快速连续地递交给相同的CPU核心将不能从本来可以实现的完全最高利用率的性能中获益如果可能我们应该构造这样的应用程序他的执行逻辑在不同的任务之间交替的频率更低。这就意味着可以成批地处理一组数据元素这也就意味可以在专门的硬件线程指CPU的逻辑核心上执行不同处理步骤。
当前的计算机为反复执行同一项任务而进行了优化:在`CPU`时钟频率保持不变的情况下,指令缓存和分支预测增加了每秒钟内可以被处理的指令数。这就意味着将不同的任务快速连续地递交给相同的`CPU`核心将不能从本来可以实现的完全(最高利用率的)性能中获益:如果可能,我们应该构造这样的应用程序,他的执行逻辑在不同的任务之间交替的频率更低。这就意味着可以成批地处理一组数据元素,这也就意味可以在专门的硬件线程(指`CPU`的逻辑核心)上执行不同处理步骤。
同样的道理也适用于对于需要同步和协调的外部[资源](#资源)的使用。当从一个单一的线程也就是CPU核心发送指令而不是从所有的CPU核心争夺带宽时由持久化存储设备所提供的I/O带宽将可以得到显著地提高。使用一个单一的入口的附加优势是多个操作可以被重新排序从而更好地适应设备的最佳访问模式当前的存储设备的线性存取性能要优于随机存取
同样的道理也适用于对于需要同步和协调的外部[资源](#资源)的使用。当从一个单一的线程(也就是`CPU`核心)发送指令,而不是从所有的`CPU`核心争夺带宽时,由持久化存储设备所提供的`I/O`带宽将可以得到显著地提高。使用一个单一的入口的附加优势是,多个操作可以被重新排序,从而更好地适应设备的最佳访问模式(当前的存储设备的线性存取性能要优于随机存取)。
此外批量处理提供了分摊昂贵的操作如I/O或者计算的成本的机会。例如将多个数据项打包到同一个网络数据包或者磁盘存储块中以提高效能并降低使用率。
此外,批量处理提供了分摊昂贵的操作(如`I/O`)或者计算的成本的机会。例如,将多个数据项打包到同一个网络数据包或者磁盘存储块中,以提高效能并降低使用率。
## 组件
我们所描述的是一个模块化的软件体系架构,其(实际上)是一个非常古老的概念,参见[Parnas(1972)](https://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf)。我们正使用组件component)”这个术语,因为它和区划compartment)”联系紧密,其意味着每个组件都是自包含的、封闭的并和其他的组件相[隔离](#隔离)。这个概念首先适用于系统的运行时特征,但是它通常也会反映在源代码的模块化结构中。虽然不同的组件可能会使用相同的软件模块来执行通用的任务,但是定义了每个组件的顶层行为的程序代码则是组件本身的一个模块。组件边界通常与问题域中的[Bounded Context](http://martinfowler.com/bliki/BoundedContext.html)密切相关。这意味着系统设计倾向于反应问题域,并因此在保持隔离的同时更加容易演化。消息[协议](#协议)为多个[Bounded Context](http://martinfowler.com/bliki/BoundedContext.html)(组件)之间提供了自然的映射和通讯层。
我们所描述的是一个模块化的软件体系架构,其(实际上)是一个非常古老的概念,参见[Parnas (1972)](https://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf)。我们正使用组件(`component`)』这个术语,因为它和区划(`compartment`)』联系紧密,其意味着每个组件都是自包含的、封闭的并和其他的组件相[隔离](#隔离)。这个概念首先适用于系统的运行时特征,但是它通常也会反映在源代码的模块化结构中。虽然不同的组件可能会使用相同的软件模块来执行通用的任务,但是定义了每个组件的顶层行为的程序代码则是组件本身的一个模块。组件边界通常与问题域中的[`Bounded Context`](http://martinfowler.com/bliki/BoundedContext.html)密切相关。这意味着系统设计倾向于反应问题域,并因此在保持隔离的同时更加容易演化。消息[协议](#协议)为多个[`Bounded Context`](http://martinfowler.com/bliki/BoundedContext.html)(组件)之间提供了自然的映射和通讯层。
## 委派
将任务[异步地](#异步的)委派给另一个[组件](#组件)意味着该任务将会在另一个组件的上下文中被执行,举几个可能的情况:这个被委派的上下文可能需要在一个不同的错误处理上下文中、在一个不同的线程上、不同的进程中或者在一个不同的网络节点上运行。委派的目的是将处理某个任务的职责移交给另一个组件,以便发起委派的组件可以执行其他的处理、或者有选择性地观察被委派的任务的进度,以防需要执行额外的操作(如处理失败或者报告进度)。
## 适应性(与"可伸缩性"对照)
<a name="适应性"></a>
## 适应性(与『可伸缩性』对照)
适应性意味着当资源根据需求按比例地增加或者减少时,系统的吞吐量将自动地向上或者向下缩放,从而满足不同的需求。系统需要具有可伸缩性(参见[可伸缩性](#可伸缩性)),以使得其可以从在运行时动态地添加或者删除资源中获益。因此,适应性是建立在可伸缩性的基础之上的,并通过添加自动地资源管理概念对其进行了扩充。
## 失败(与“错误”对照)
<a name="失败"></a>
## 失败(与『错误』对照)
失败是服务中的意外事件,其阻止了服务继续正常地运行。失败通常会阻止对于当前的、并可能所有接下来的客户端请求的响应。和错误相对照,错误是意料之中的,并且针对各种情况进行了处理 —— 例如在输入验证的过程中所发现的错误将会作为该消息的正常处理过程的一部分返回给客户端。而失败是意料之外的并且在系统能够恢复至和之前相同的服务水平之前需要进行干预。这并不意味着失败总是致命的fatal虽然在失败发生之后系统的某些服务能力可能会被降低。错误是正常操作流程的预期部分在错误发生之后系统将会立即地对其进行处理并将继续以相同的服务能力继续运行。
失败是服务中的意外事件,其阻止了服务继续正常地运行。失败通常会阻止对于当前的、并可能所有接下来的客户端请求的响应。和错误相对照,错误是意料之中的,并且针对各种情况进行了处理 —— 例如,在输入验证的过程中所发现的错误,将会作为该消息的正常处理过程的一部分返回给客户端。而失败是意料之外的,并且在系统能够恢复至(和之前)相同的服务水平之前,需要进行干预。这并不意味着失败总是致命的(`fatal`),虽然在失败发生之后,系统的某些服务能力可能会被降低。错误是正常操作流程的预期部分,在错误发生之后,系统将会立即地对其进行处理,并将继续以相同的服务能力继续运行。
失败的例子有:硬件故障、由于致命的资源耗尽而引起的进程意外终止以及导致系统内部状态损坏的程序缺陷。
## 隔离(以及“遏制”)
<a name="隔离"></a>
## 隔离(以及『遏制』)
隔离可以定义为在时间和空间上解耦。在时间上解耦意味着发送者和接收者可以拥有独立的生命周期 —— 他们不需要在同时存在以使得相互通信成为可能。通过在[组件](#组件)之间添加[异步](#异步)边界,以及通过[消息传递](#消息驱动)实现了这一点。在空间上解耦(定义为[位置透明性](#位置透明性))意味着发送者和接收者不必运行在同一个进程中。不管运维部门或者运行时本身决策的部署结构是多么的高效 —— 但是在应用程序的生命周期之内,这一切都可能会发生改变。
真正的隔离超出了大多数面向对象的语言中的常见的封装概念,并使得我们可以划分和遏制:
- 状态和行为:它支持无共享的设计,并最大限度地减少了竞争和一致性成本([如普遍性的伸缩性原则Universal Scalability Law](http://www.perfdynamics.com/Manifesto/USLscalability.html)中所定义的)。
- 失败:它支持在细粒度上捕获、发出失败信号以及管理[失败](#失败)而不是将其扩散cascade到其他组件。
- 状态和行为:它支持无共享的设计,并最大限度地减少了竞争和一致性成本([如普遍性的伸缩性原则(`Universal Scalability Law`](http://www.perfdynamics.com/Manifesto/USLscalability.html)中所定义的)。
- 失败:它支持在细粒度上捕获、发出失败信号以及管理[失败](#失败),而不是将其扩散(`cascade`)到其他组件。
组件之间的强隔离是建立在基于良好定义的[协议](#协议)的通信之上的,并支持解耦,从而使得系统更加容易被理解、扩展、测试和演化。
## 位置透明性
[适应性](#适应性)系统需要自适应并不间断地对需求的变化做出反应。他们需要优雅而高效地扩大或者缩减部署规模。极大地简化这个问题的一个关键洞察是认识到我们一直都在处理分布式计算。无论我们是在一台单独的具有多个独立的通过快速通道互联QPI进行通信的CPU的节点之上还是在一个具有多台通过网络进行通信的独立节点的机器集群之上运行我们的系统都是如此。拥抱这一事实意味着在多核心之上进行垂直缩放和在集群之上进行水平伸缩并没有什么概念上的差异。
[适应性](#适应性)系统需要自适应,并不间断地对需求的变化做出反应。他们需要优雅而高效地扩大或者缩减(部署)规模。极大地简化这个问题的一个关键洞察是认识到我们一直都在处理分布式计算。无论我们是在一台单独的(具有多个独立的通过快速通道互联(`QPI`)进行通信的`CPU`的)节点之上,还是在一个(具有多台通过网络进行通信的独立节点的)机器集群之上运行我们的系统,都是如此。拥抱这一事实意味着,在多核心之上进行垂直缩放和在集群之上进行水平伸缩并没有什么概念上的差异。
如果我们所有的[组件](#组件)都支持移动性,而本地通信只是一项优化。那么我们根本不需要预先定义一个静态的系统拓扑和部署结构。可以将这个决策留给运维人员或者运行时,他们可以根据系统的使用情况来对其进行调整和优化。
这种通过[异步的](#异步的)[消息传递](#消息传递)实现的空间上的(请参见[隔离](#隔离)的定义)解耦,以及运行时实例和他们的引用的解耦就是我们所谓的位置透明性。位置透明性通常被误认为是透明的分布式计算然而实际上恰恰相反通过将他们作为编程模型中的一等公民我们拥抱网络以及它所有的约束——如部分失败、网络分裂、消息丢失以及它的异步性和与生俱来的基于消息的性质而不是尝试在网络上模拟进程内的方法调用如RPC、XA等)。我们对于位置透明性的观点与Waldo等人的[A Note On Distributed Computing](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.7628)完全一致。
这种通过[异步的](#异步的)[消息传递](#消息传递)实现的空间上的(请参见[隔离](#隔离)的定义)解耦,以及运行时实例和他们的引用的解耦就是我们所谓的位置透明性。位置透明性通常被误认为是透明的分布式计算,然而实际上恰恰相反:通过将他们作为编程模型中的一等公民,我们拥抱网络,以及它所有的约束 —— 如部分失败、网络分裂、消息丢失,以及它的异步性和与生俱来的基于消息的性质,而不是尝试在网络上模拟进程内的方法调用(如`RPC``XA`等)。我们对于位置透明性的观点与 _Waldo_ 等人的[_A Note On Distributed Computing_](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.7628)完全一致。
## 消息驱动(与事件驱动对照)
<a name="消息驱动"></a>
## 消息驱动(与『事件驱动』对照)
消息是发送到特定目的地的数据项,事件是[组件](#组件)在达到了某个给定状态时所发出的信号。在消息驱动的系统中,可寻址的接收者等待消息的到来,并对他们做出反应,否则只是休眠(即异步非阻塞地等待消息的到来)。在事件驱动的系统中,通知监听器被附加到了事件源,以便在事件被发出时被调用(指回调)。这也就意味着,事件驱动的系统关注于可寻址的事件源,而消息驱动的系统则着重于可寻址的接收者。消息可以包含编码为它的有效载荷的事件。
由于事件消耗链的短暂性,在事件驱动的系统中很难实现弹性:当处理过程已经开始,监听器已经设置好,以便对响应结果并对结果进行变换时,这些监听器通常都直接地处理成功或者[失败](#失败),并向原始的客户端报告执行结果。响应组件的失败,以便于恢复他(指失败的组件)的正常功能,在另外一方面,需要处理的是那些并没有与短暂的客户端请求捆绑在一起的,而是影响了整个组件的健康状况的失败。
由于事件消耗链的短暂性,在事件驱动的系统中很难实现弹性:当处理过程已经开始,监听器已经设置好,以便对响应结果并对结果进行变换时,这些监听器通常都直接地处理成功或者[失败](#失败),并向原始的客户端报告执行结果。响应组件的失败,以便于恢复他(指失败的组件)的正常功能,在另外一方面,需要处理的是那些并没有与短暂的客户端请求捆绑在一起的,而是影响了整个组件的健康状况的失败。
## 非阻塞的
在并发编程中,如果争夺资源的线程并没有被保护该资源的互斥所无限期地推迟执行,那么该算法则被认为是非阻塞的。在实践中,这通常说缩影为一个 API当资源可用时该API将允许访问该资源否则它将会立即地返回并通知调用者该资源当前不可用或者该操作已经启动了但是还没有完成。对于某个资源的非阻塞 API 使得调用者可以进行其他的操作,而不是被阻塞以等待该资源变为可用。此外,还可以通过允许该资源的客户端注册,以便让其在该资源可用的或者该操作已经完成时获得通知。
在并发编程中,如果争夺资源的线程并没有被保护该资源的互斥所无限期地推迟执行,那么该算法则被认为是非阻塞的。在实践中,这通常说缩影为一个`API`,当资源可用时,该`API`将允许访问该资源,否则它将会立即地返回,并通知调用者该资源当前不可用,或者该操作已经启动了但是还没有完成。对于某个资源的非阻塞`API`使得调用者可以进行其他的操作,而不是被阻塞以等待该资源变为可用。此外,还可以通过允许该资源的客户端注册,以便让其在该资源可用的或者该操作已经完成时获得通知。
## 协议
协议定义了在[组件](#组件)之间交换或者传输消息的方法与规范。协议由会话参与者之间的关系、协议的累计状态以及允许发送的消息集所构成。这意味着,协议描述了会话参与者在何时可以发送什么样的消息给另外一个会话参与者。协议可以按照消息交换的形式进行分类,一些常见的类型是请求——响应模式、重复的请求——响应模式(如 HTTP 中)、发布——订阅模式、以及(反应式)流模式(同时包含(动态地)推送和拉取)。
协议定义了在[组件](#组件)之间交换或者传输消息的方法与规范。协议由会话参与者之间的关系、协议的累计状态以及允许发送的消息集所构成。这意味着,协议描述了会话参与者在何时可以发送什么样的消息给另外一个会话参与者。协议可以按照消息交换的形式进行分类,一些常见的类型是请求 —— 响应模式、重复的请求 —— 响应模式(如`HTTP`中)、发布 —— 订阅模式、以及(反应式)流模式(同时包含(动态地)推送和拉取)。
和本地编程接口相比,协议更加通用,因为它可以包含两个以上的参与者,并且可以预见到消息交换的进展,而接口只指定了调用者和接收者之间每次一次的交互。
@@ -95,15 +99,15 @@
## 资源
[组件](#组件)执行其功能所依赖的一切都是资源,资源必须要根据组件的需要而进行调配。这包括 CPU 的分配、内存以及持久化存储以及网络带宽、内存带宽、CPU 缓存、内部插座的 CPU 链接、可靠的计时器以及任务调度服务、其他的输入和输出设备、外部服务(如数据库或者网络文件系统等)。所有的这些资源都必须要考虑到[适应性](#适应性)和弹性,因为缺少必需的资源将妨碍组件在被需要时发挥正常作用。
[组件](#组件)执行其功能所依赖的一切都是资源,资源必须要根据组件的需要而进行调配。这包括`CPU`的分配、内存以及持久化存储以及网络带宽、内存带宽、`CPU`缓存、内部插座的`CPU`链接、可靠的计时器以及任务调度服务、其他的输入和输出设备、外部服务(如数据库或者网络文件系统等)。所有的这些资源都必须要考虑到[适应性](#适应性)和弹性,因为缺少必需的资源将妨碍组件在被需要时发挥正常作用。
## 可伸缩性
一个[系统](#系统)通过利用更多的计算[资源](#资源)来提升其性能的能力,是通过系统吞吐量的提升比上资源的增加的比值来衡量的。一个完美的可伸缩性系统的特点是这两个数字是成正比的。所分配的资源加倍也将使得吞吐量翻倍。可伸缩性通常受限于系统中所引入的瓶颈或者同步点,参见[Amdahl 定律以及 Gunther 的通用可伸缩模型( Amdahls Law and Gunthers Universal Scalability Model](http://blogs.msdn.com/b/ddperf/archive/2009/04/29/parallel-scalability-isn-t-child-s-play-part-2-amdahl-s-law-vs-gunther-s-law.aspx)。
一个[系统](#系统)通过利用更多的计算[资源](#资源)来提升其性能的能力,是通过系统吞吐量的提升比上资源的增加的比值来衡量的。一个完美的可伸缩性系统的特点是这两个数字是成正比的。所分配的资源加倍也将使得吞吐量翻倍。可伸缩性通常受限于系统中所引入的瓶颈或者同步点,参见[_Amdahl_ 定律以及 _Gunther_ 的通用可伸缩模型Amdahls Law and Gunthers Universal Scalability Model](http://blogs.msdn.com/b/ddperf/archive/2009/04/29/parallel-scalability-isn-t-child-s-play-part-2-amdahl-s-law-vs-gunther-s-law.aspx)。
## 系统
系统为它的[用户](#用户)或者客户端提供服务。系统可大可小,他们可以包含许多组件或者少数几个组件。系统中的所有组件相互协作以提供这些服务。在很多情况下,位于相同系统中的多个组件具有某种客户端——服务器关系(例如考虑一下,前端组件依赖于后端组件)。一个系统将共享了一个通用的弹性模型,我们的意思是,某个组件的[失败](#失败)将会在该系统的内部得到处理,并从一个组件[委派](#委派)给其他组件。如果系统中的一组组件的功能、资源或者失败模型都和系统中的其余部分相互[隔离](#隔离),那么将这组组件看作是系统的子系统将有所脾益。
系统为它的[用户](#用户)或者客户端提供服务。系统可大可小,他们可以包含许多组件或者少数几个组件。系统中的所有组件相互协作以提供这些服务。在很多情况下,位于相同系统中的多个组件具有某种客户端 —— 服务器关系(例如考虑一下,前端组件依赖于后端组件)。一个系统将共享了一个通用的弹性模型,我们的意思是,某个组件的[失败](#失败)将会在该系统的内部得到处理,并从一个组件[委派](#委派)给其他组件。如果系统中的一组组件的功能、资源或者失败模型都和系统中的其余部分相互[隔离](#隔离),那么将这组组件看作是系统的子系统将有所脾益。
## 用户