移动设备的普及以及它们之间的互联互通创造了新的应用机遇。这些新应用不再局限于单一系统空间,而是分布在多个系统空间中。这种应用从单系统空间、基于主机的系统向多系统空间解决方案的转变,正受到停留在旧的顺序计算模型中的软件工具集的阻碍。
本文将这种新需求定义为网络应用。文章论证了当前基于计算的编程不是正确的模型,并建议应用开发必须从基于计算前提的软件转向基于通信或交互前提的软件。文章最后通过一个使用交互开发的简单 CRUD(创建、读取、更新、删除)应用程序来说明这一点,阐述了挑战,并解释了这样一个系统将如何以交互为中心运作,而不是以算法为中心。
想象一下未来患者与医生的会面场景,患者拥有个人 EMR(电子病历)设备,通过 NFC(近场通信)波或将 EMR 设备物理扫描到接收器中,向医生办公室识别身份。EMR 设备与医生办公室系统对话,提供所有必要的信息。处方可以直接发送到药房,并为 EMR 提供同步点。因此,当患者去药房时,药物会被交付给患者,因为 EMR 可以与药房同步。
这就是网络时代,需要新的软件方法。限制于单一系统空间的以主机为中心的编程将不足以满足这个新数字时代的多系统空间需求。
应用程序有两种类型:独立式和网络式。2,9 诸如 PC 上的文字处理、大型机上的多用户编程,或使用 SOAP(简单对象访问协议)或 ORB(对象请求代理)的分布式计算等应用程序都是独立式的。独立式应用程序通过具有单一入口点(即,调用程序将控制权交给应用程序,并在应用程序完成后取回控制权)为应用程序程序员提供单一机器视图9。应用程序通过执行与主例程并行运行的 I/O 例程来访问环境中的数据。程序由机器中的程序计数器控制。独立式应用程序运行在机器(虚拟或真实)之上。
在 EMR 应用程序示例中,请注意程序员如何不将应用程序视为一个分层程序,而是视为不同人员通过设备网络进行的交互。与独立式应用程序不同,网络应用程序在不同代理通过其操作相互交互时推进。这些操作接受来自网络上代理的应用程序状态更改,并且还影响网络上其他代理的应用程序状态更改。基于网络的应用程序运行在网络基础设施之上。
现代数字时代需要人员和设备协同工作,以创造整体业务体验。所有这些位于不同系统空间的不同计算代理应彼此通信。简单来说,他们应该互相询问和告知,以创建完整的解决方案。这种数字时代的事件编排同时发生,因此是一个并发问题。
编程由顺序运算符(如在 Java 中)或赋值运算符分隔的语句组成。这些运算符将表达式的值分配到内存位置,并指示编译器移动到下一条指令。语言的这两个基本构造使编程变得非常顺序化。在并发世界中使用顺序约束进行编程,给程序员带来了巨大的挑战。
通常,使程序工作的有两个主要部分。一个是程序的控制,另一个是控制向前移动时传输的数据。控制是程序正在运行的光标。在顺序编程中,控制从上到下移动。更改程序控制的唯一方法是使用:(a)goto 语句;(b)异常语句;和(c)迭代/循环语句。编程包括准备数据,以便处理器可以处理信息。软件的创造性部分是通过操纵程序控制来建立的。操纵分层程序来表示各种模型很难实现,因此会导致错误。
在顺序程序中,假定程序控制向前移动。语言本身没有任何设施来处理跨系统空间的处理。如果部分执行位于另一个系统空间中,那么如何处理控制问题?语言如何具有足够的概念来处理多系统空间计算的不同问题,例如(a)转移控制;(b)处理延迟;和(c)处理异常?一段代码如何告知位于不同系统空间中的另一段代码,它已成功继续或已抛出异常。这些语言中没有任何东西支持这些问题。它们假设只有一个系统空间,并且处理器中的控制将向前移动到下一步。
数字时代解决方案必须将人员和设备协调为对等协作系统。从顺序程序创建此类协作系统是一个巨大的挑战。是否有更好的方法可以更直接地表达这些并发系统,从而使数字解决方案更容易实现?为此,需要消除程序的基本默认顺序控制。默认顺序控制使得表达并发问题更加困难,因为程序员必须操纵顺序控制来创建并发性。
最大的问题之一是在系统空间之间共享状态。在当前的编程范例中,状态是使用函数和变量来检查的。这些仅在语言的约束范围内可用,并且不会暴露在操作系统语言之外。为了克服这个问题,语言本身应该具有共享状态(程序控制和数据)的设施,以便客户端可以检查它。
在某些情况下,应用程序知道数据的位置,但不确定所有数据何时到达。这使得当前程序的确定性本质不适用。数字时代数据的这种不确定性导致了当前编程无法解决数字时代问题。虽然基本编程没有处理非确定性系统的方法,但现在通过遵循一种称为反应式编程的新编程范例来实现。3,8
一旦程序的状态和控制被共享,是否有可能确保只有授权人员才能访问这两个关键要素?当前的编程语言没有隐藏信息的概念。理想情况下,编程语言应该具有共享状态的设施,并提供对此状态的有控制的选择性访问。
一个可以跨系统空间工作的网络应用程序需要一种看待计算问题的新方法。与其将计算思想(过程、函数等)作为基础,不如将通信思想作为良好的网络应用程序编程范例的基础。
考虑两个算术表达式:Y=X+A 和 A=B+C。使用现在使用的顺序程序,这些表达式按顺序编写为 { A=B+C; Y=X+A }。程序按顺序运行以获得答案。如果它们意外地写成 { Y=X+A; A=B+C },程序将继续运行,但答案将是错误的(即,一个错误)。有没有办法消除这种异常?
以稍微不同的方式想象一下。在相同的计算中,表达式并发运行,并在 A 共享时组合——也就是说,组合由两个代理组成,A=B+C 和 Y=X+A,它们并发运行(图 1)。算术表达式的右侧是值的接收器,表达式的左侧是信息的来源。因此,在 A=B+C 的情况下,B 和 C 是接收器,A 是来源。当 B 和 C 到达并提升 A 时,A=B+C 被解析。同时,Y=X+A 正在等待 X 和 A。假设 X 已经到达,当第一个计算提升 A 时,它会被第二个计算自动消耗以提升答案 Y。
请注意,在这种情况下,代理并发运行,但由于第二个代理正在等待 A,因此由第一个代理提升。这两个计算是并发的。这两个代理被组合在一起,但它们暴露了组合操作(即,它们接受 C、B 和 X 并产生 Y)。这消除了顺序语言中因乱序编码而引起的错误倾向。
整个计算并行运行并自我驱动,这取决于值的到达。计算不再是关于算法,而是关于在两个活动计算代理之间通信值。数据的流动是通过命名两个变量来完成的。
因此,要将 Y 流向另一个代理,只需将 AgentCombinator 与将要消耗 Y 的算术代理组合即可。为了定义这种通信,控制是通过将通信分成两部分来建立的:一部分表示信息的给予,另一部分表示信息的接收。
使计算并发:(a)解决计算速度问题,(b)消除计算乱序编码时出现错误的问题,以及(c)使计算网络化和非确定性。显然,计算最好表示为通信。
与独立式应用程序不同,网络应用程序没有单一机器视图。网络应用程序是由许多并发运行的机器组成的群,也称为代理。这些代理驻留在单个或多个系统空间中,协调它们的工作以创造体验。每个代理可能在一个实例中充当客户端,在另一个实例中充当服务器。
无论是独立式还是网络式,一个连贯的应用程序都具有某些显著的特性。
应用程序控制设置了程序的节奏。一旦程序从操作系统(通过 C 语言中的 main()
函数)或服务情况下的 Web 服务器获得控制权,程序员就可以通过应用所用语言提供的不同控制语句来管理程序控制。程序完成后,控制权将移交给操作系统或服务启动器。
软件的魔力是通过根据语言规则控制这些指令的组织方式来实现的。为了便于说明,请考虑 C 语言。4 程序员唯一可用的控制元素是函数语句、赋值和循环语句。程序员使用这些构造来构建应用程序流程(图 2)。
一旦 C 语言中的独立式应用程序收到控制权,程序将通过运行函数来执行输入/输出与外界交互(图 3)。在 I/O 语句期间,程序被阻塞。现在正变成一个多系统空间的世界,期望状态可以被另一个程序观察到。程序及其语言应具有在运行时动态共享数据的符号和概念,而无需额外的工程。
独立式应用程序控制有两个要素:(1)控制的前进和返回移动,以及(2)在这些移动期间的数据传输。在当前的编程模型中,由于处理器状态机(及其当前程序计数器)的限制,控制和数据的前进和返回移动是同步的(即,调用者暂停,直到调用控制权交还给调用者)。
现在快进到本文开头提到的未来患者与医生的会面场景。在这种情况下,不同的设备,也称为代理,彼此对话以推动流程前进。它不是单主机系统,而是相互对话的分布式设备的集合,构成一个完整的、完整的自我。在这个新世界中,没有语句或赋值——只有一系列交互或同步点。如何在没有单一控制点的情况下表达这个新世界?如何在没有传统意义上的明显程序控制的情况下表示这个新世界?
为了使这成为可能,让我们探索同一个独立式应用程序,并尝试通过将其作为网络应用程序交付来实现相同的控制流程。为了将示例应用程序网络化,三个组件——caller
、main
和 print
——作为三个独立的代理运行(图 4)。连接这些代理允许它们在网络环境中交付相同的打印功能。调用者代理通过在 main
操作上发送数据并等待 rtnMain
操作来启动计算。main
代理由两个独立的代理组成,一个监听 main
操作,另一个监听 rtnPrint
。接收 main
操作的第一个组件代理打开 print
。同时,一个 print
代理监听 print
,并在屏幕上打印后,打开 rtnPrint
。另一个 main 代理响应 rtnPrint
并打开 rtnMain
。请注意,每个代理都独立运行,但由不同的操作或同步点协调。由于 rtnMain
仅在打印完成后才被触发,因此功能与第一个 C 程序相同。不同之处在于如何通过协调自主代理来实现功能:CallerAgent
、MainAgent
和 PrintAgent
。这些代理也可以跨多个系统空间工作。
将应用程序控制从计算转移到通信,使应用程序能够在多个系统空间中连贯地工作。
如前所述,简单的 C 程序曾经是一个独立式应用程序,现在通过将其从计算前提转移到通信前提来表示为网络应用程序。同步点(如 main
、rtnMain
、print
和 rtnPrint
)协调这些代理以创建一个连贯的整体。这些协调元素可以位于单个系统空间中,也可以跨多个系统空间。如果这些同步点位于跨地址空间,则会引入一个新的约束:网络延迟。
这现在确定了整个应用程序的速度。在典型的网络应用程序中,当应用程序不使用网络时,延迟会减少。通过引入缓存,减少了网络使用量,从而提高了整个应用程序的速度。
信息隐藏是计算机系统的重要属性。编程语言应该很好地支持这一点。为了说明,面向对象编程允许程序员定义信息的可见性为私有或公共。当为私有时,信息仅对对象可见。如果变量声明为公共,则信息对整个程序可见。这些声明是指示编译器控制信息可见性的指令。运行时信息可见性必须由程序员在设计和构建期间完成。在内存中进行此类信息隐藏对于独立式应用程序来说很好,但对于网络应用程序,语言也应支持跨网络的作用域。这是如何实现的?
在网络应用程序中,状态转换作为同步点公开。此外,信息通过同步点传输。客户端可以通过与这些同步点交互来影响应用程序。在图 5 中,服务器有两个同步点:pa1
,它是 隐藏的,因此客户端无法观察到,以及 pa2
, 它是 开放的,可以被所有客户端观察到。在这种配置中,只有 client1
知道 pa1
,因此服务器只能被 client1
影响。按照面向对象原则,pa1
是私有的,pa2
是公共的。此原则用于控制跨网络的信息可见性。作用域是通过从公众隐藏操作,然后有选择地将同步名称给予不同代理来控制的。这些客户端和服务器中的每一个都可能跨越许多地址空间存在,从而在网络上创建受控的信息安全性。
网络应用程序带来了新的挑战,例如多系统空间、延迟、间歇性网络可用性和安全性。将应用程序视为通信而不是函数可以克服这些挑战。
网络应用程序应该使用以通信为基础的工具集和语言来开发。基于计算的软件具有良好的理论基础,例如 λ 演算,整个编程概念都建立在其之上。基于 λ 演算的应用程序在程序执行时将世界拒之门外,而网络应用程序本质上具有许多在网络上相互交互的代理。应用程序性质的这种差异要求为构建网络应用程序的工具集和语言建立新的基础。
π 演算6,7,即通信和移动系统理论,是 Petri 网的代数表示。π 演算的重点是定义网络上运行的两个代理之间的通信。它还可以定义网络上代理的配置如何随着它们的交互而变化。π 演算的这一特性——建模独立运行的多个代理之间交互的能力——使其成为构建网络应用程序工具集和语言的理想数学基础。
π 演算通过以下方式实现这一点:(a)将代理行为表示为操作;(b)将不同的代理配置为初始启动配置;(c)表示这些代理之间的共享转换;以及(d)随着状态转换的发生而更改代理网络的配置。π 演算代理操作可以被观察到。由 x
表示的操作是接收信息的潜力。由 x̄
表示的操作是成为信息来源的潜力。这些互补操作的反应推动了过程和数据从源到目标的移动。
图 6 详细说明了初始配置 P
。这取自 Milner 的Communicating and Mobile Systems: the Pi-Calculus 第 88 页。6 这些术语彼此并发运行。并行操作由运算符“|
”标识。序列操作由“.
”表示。不同的操作是 x
和 u
。操作 x
通过 u
进行。操作 u
通过 v
传输。
π 演算引擎执行交互(即,它查看具有相同名称的操作并执行反应)。当反应发生时,值从一个术语传递到另一个术语。在 x
和 x̄
之间反应的情况下,它将通过 x
发送 z
。随着反应的发生,第二个术语变得惰性,用 0
表示——一个没有操作的术语。然后,如图 7 所示,它继续用 z
替换 u
以提升最终配置过程状态 P1
。请注意,不同的术语节点如何折叠以创建最终状态。
通过设计一种基于 π 演算(即,基于交互)的语言,并在执行该语言作为反应的反应引擎上运行它,可以将编程从计算转向通信——以网络为中心的编程。
当基于通信时,网络应用程序是最佳解决方案。与计算的功能模型(它具有将数据从一个变量移动到另一个变量的函数)不同,在网络应用程序中,数据的移动是通过通信完成的。与物理学一样,电流的流动是由电势定义的。类似地,网络应用程序是通过建立通信电势,然后将它们连接在一起以产生火花来定义的,这确保了信息从源到接收器的流动。
构建网络应用程序的第一步是定义当这个火花发生时会发生什么流动。定义此操作然后定义哪些元素通过它流动。一旦定义了操作,然后通过创建 +ve
和 -ve
来设置此操作的两个电势。+ve
是信息的来源(如 π 演算中的 x̄
),-ve
(如 π 演算中的 x
)是信息的接收器。Tell
设置信息的 +ve
来源,Ask
设置信息的 -ve
接收器。
Hello World 网络应用程序有两个并发运行的代理来交付功能。MainAgent
由两个操作序列组成,每个序列包含两个操作。当此代理被激活时,它同时激活 main
和 rtnPrint
MainAgent = Compose [
Sequence [ Ask(main); Tell(print)]; Sequence [ Ask(rtnPrint); Tell(rtnMain)]
]
第二个代理是 PrintAgent
PrintAgent = Sequence [ Ask(print); Tell(rtnPrint) ]
Hello World 应用程序由这两个并发运行的代理组成。它被定义为
HelloWorldApplication = Compose [ MainAgent; PrintAgent]
图 8 中的表格显示了当每个操作被交互时,哪些操作处于开启状态。首先,所有代理都变为活动状态,并且 main
、rtnPrint
和 print
操作在 Ask
侧 (-ve
) 公开。main
操作将被公开,因此可以从用户界面进行交互。当与 main
交互时,它会在 Tell
侧 (+ve
) 激活 print
。现在,相同的名称 print
在 +ve
和 -ve
侧都处于活动状态,为火花产生创造了条件。接下来,在 print
上发生交互,在 Tell
侧 (+ve
) 打开 rtnPrint
。这导致与 rtnPrint
交互,从而导致下一组交互。交互的跟踪如图 8 所示。
这些操作表示为 REST URI(统一资源标识符),因此可以通过网络进行交互。网络编程就像将代理配置到配置中,以促成这些交互一样简单。
MasterKube 软件技术5 的构建考虑了这种网络应用程序。MasterKube 软件范例用于构建一个简单的 CRUD 应用程序。
第一步是定义将暴露给外部系统的所有操作。任何理解 MasterKube XML 响应的客户端 UI 都可以观察到这些操作。在本例中,有用于 Add
、Edit
、View
和 Delete
的操作
<Actions>
<Action>
<Element>FirstName</Element>
<Element>LastName</Element>
<Element>EmailId</Element>
<ActionName>View</ActionName>
</Action>
<Action>
<Element>FirstName</Element>
<Element>LastName</Element>
<Element>MobileNumber</Element>
<Element>EmailId</Element>
<ActionName>Delete</ActionName>
</Action>
<Action>
<Element>FirstName</Element>
<Element>LastName</Element>
<Element>MobileNumber</Element>
<Element>EmailId</Element>
<ActionName>Edit</ActionName>
</Action>
<Action>
<Element>FirstName</Element>
<Element>LastName</Element>
<Element>MobileNumber</Element>
<Element>EmailId</Element>
<ActionName>Add</ActionName>
</Action> </Actions>
代理提供应用程序的动态部分。以下代码中的代理 AddContactAgent
显示了操作 Add
,当与该操作交互时,会创建一个新代理。AddContactAgent
显示了 Add
UI。在与 Add
操作交互时,它会创建 Contact
,并重复 AddContactAgent
以显示相同的操作。
<Agent>
<AgentName>AddContactAgent</AgentName>
<Sequence>
<!--当按下添加操作时触发联系人代理 -->
<AgentCommand> <AgentName>ContactAgent</AgentName>
<Ask><action><actionName>Add</actionName></action></Ask>
</AgentCommand>
<!-- 因为此代理处于序列操作中,所以会递归调用相同的代理 -->
<AgentCommand> <AgentName>AddContactAgent</AgentName> </AgentCommand>
</Sequence>
</Agent>
ContactAgent
接受 FirstName
、LastName
、MobileNumber
和 EmailId
。它激活 EditContactAgent
。代理的标识方式 AvatarName
是 LastName
。
<Agent>
<AgentName>ContactAgent</AgentName>
<ProcessName>Contacts</ProcessName>
<AvatarName>LastName</AvatarName>
<Element>FirstName</Element> <Element>LastName</Element><Element>MobileNumber</Element><Element>EmailId</Element>
<Compose>
<!-- 重复显示编辑联系人代理,直到用户按下删除 -->
<AgentCommand><AgentName>EditContactAgent</AgentName></AgentCommand>
</Compose>
</Agent>
EditContactAgent
显示联系人显示的不同操作。为每个联系人启用的不同操作是 Edit
、Delete
和 View
。这些操作在选择中显示,因为只能采取一个操作。与一个选项交互后,其他操作将消失。
<Agent>
<AgentName>EditContactAgent</AgentName>
<Compose>
<!-- 呈现两个选择。一个是编辑,另一个是删除 -->
<Choice> <ChoiceOption>
<Ask><action><actionName>Edit</actionName></action></Ask>
<OptionAction>
<Compose>
<!-- 当与编辑交互时,会重复相同的代理以显示持久性 -->
<AgentCommand> <AgentName>EditContactAgent</AgentName> </AgentCommand>
</Compose> </OptionAction>
</ChoiceOption>
<ChoiceOption>
<Ask><action><actionName>Delete</actionName></action></Ask>
<OptionAction> <!-- 当与删除交互时,不会公开进一步的观察结果,因此此联系人消失。 --> </OptionAction>
</ChoiceOption>
<ChoiceOption>
<Tell><action><actionName>View</actionName></action></Tell>
<OptionAction>
<!-- 当与查看交互时,会重复相同的代理以显示持久性 -->
<AgentCommand><AgentName>EditContactAgent</AgentName></AgentCommand></OptionAction>
</ChoiceOption></Choice>
</Compose>
</Agent>
当与 Edit
交互时,它会显示与 Edit
操作中所有元素的交互。这些元素预计会被输入。在接受这些值进入系统后,EditContactAgent
会重复。重复相同的代理再次给出 Edit
、Delete
和 View
操作的选择,从而展现持久的行为。
在 Delete
操作中,Choice
操作为空。由于没有观察结果,与 Delete
交互不会留下进一步的观察结果,因此该联系人被视为已删除。
所有这些操作都作为 REST URL 公开,任何设备都可以解释它们。
设备的微型化以及这些设备通过高速无线网络的广泛互联,正在彻底改变商业的运作方式。这些变化(又名数字化)将深刻地改变企业的运营方式。软件是这个数字世界的中心,但软件工具集和语言是为主机时代构思的。已经困扰软件实践的问题(例如高缺陷、低软件生产力、信息漏洞、低软件项目成功率等)在这种方法下将更加严重。现在是时候让软件变得更简单、更安全、更可靠了。
将软件从其计算基础转移到通信基础将确保数字化的承诺和好处得到更广泛的分享。
1. Backus, J. 1978. Can programming be liberated from the von Neumann style? A functional style and its algebra of programs. Communications of the 21(8):613-641; http://dl.acm.org/citation.cfm?doid=359576.359579.
2. Fielding, R. T. 2000. Architectural styles and the design of network-based software architectures. Ph.D. dissertation, University of California, Irvine; https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm.
3. Futures and promises. The Boost C++ Libraries; http://theboostcpplibraries.com/boost.thread-futures-and-promises.
4. Kernighan, B., Ritchie, D. M. 1978. The C Programming Language. Prentice Hall.
5. MasterKube Software Development Manual. 2014
6. Milner, R. 1999. Communicating and Mobile Systems: The Pi-Calculus. Cambridge University Press.
7. Milner, R. 1993. Elements of Interaction. Communications of the 36(1): 78-89; http://dl.acm.org/citation.cfm?id=1283948.
8. ReactiveX; https://reactivex.fullstack.org.cn/intro.html.
9. Tanenbaum, A. S., van Renesse, R. 1985. Distributed operating systems. Computing Surveys 17(4): 419-470.
数据中心网络漫游指南
良好的用户体验取决于数据中心网络内可预测的性能。
丹尼斯·阿布茨,鲍勃·费尔德曼,谷歌
https://queue.org.cn/detail.cfm?id=2208919
你对网络性能一窍不通
带宽只是问题的一部分。
凯文·福尔,英特尔研究院,史蒂夫·麦肯,河床公司
https://queue.org.cn/detail.cfm?id=1066069
网络的新角色
面向应用程序的网络可以帮助弥合企业之间的差距。
Taf Anthias 和 Krishna Sankar,思科系统
https://queue.org.cn/detail.cfm?id=1142069
Antony Alappatt 是 MasterKube 的创始人,其目标是提供突破性的软件技术和服务,以服务于新的数字时代。 他在班加罗尔的 RV 工程学院获得了 B.E. 学位。 MasterKube 以其创新技术,被印度政府评选为印度前 50 名创新企业之一。 他与妻子和两个孩子住在钦奈。 他喜欢倾听和讨论新想法,您可以通过 [email protected] 联系他。
版权所有 © 2017,归所有者/作者所有。 出版权已授权给 。
最初发表于 Queue vol. 15, no. 4—
在 数字图书馆 中评论这篇文章
David Collier-Brown - 你不了解带宽
当您的员工或客户说他们的互联网性能很差时,带宽可能不是问题。 一旦他们拥有 50 到 100 Mbps 范围内的带宽,问题就是延迟,即 ISP 的路由器处理他们流量所需的时间。 如果您是 ISP 并且所有客户都讨厌您,请振作起来。 这现在是一个可以解决的问题,这要归功于一群敬业的人,他们找到了问题,解决了问题,然后在家庭路由器中验证了他们的解决方案。
Geoffrey H. Cooper - 使用 FDO 和不受信任的安装程序模型的设备入职
设备的自动入职是处理正在安装的越来越多的“边缘”和物联网设备的重要技术。 设备的入职与大多数设备管理功能不同,因为设备的信任从工厂和供应链转移到目标应用程序。 为了通过自动入职加快流程,供应链中的信任关系必须在设备中正式化,以允许自动化过渡。
Brian Eaton, Jeff Stewart, Jon Tedesco, N. Cihan Tas - 通过关键路径跟踪进行分布式延迟分析
低延迟是许多 Google 应用程序(如搜索)的重要功能,延迟分析工具在维持大规模低延迟方面发挥着关键作用。 对于包含功能和数据不断发展的服务的复杂分布式系统,将总体延迟保持在最低水平是一项具有挑战性的任务。 在大型、真实的分布式系统中,现有的工具(如 RPC 遥测、CPU 性能分析和分布式跟踪)对于理解整个系统的子组件很有价值,但不足以在实践中执行端到端延迟分析。
David Crawshaw - VPN 的一切焕然一新
VPN(虚拟专用网络)已有 24 年的历史。 这个概念是为与我们今天所知的互联网截然不同的互联网而创建的。 随着互联网的增长和变化,VPN 用户和应用程序也随之增长和变化。 VPN 在 2000 年代的互联网中经历了尴尬的青春期,与其他广泛流行的抽象概念交互不良。 在过去的十年中,互联网再次发生了变化,这个新的互联网为 VPN 提供了新的用途。 全新协议 WireGuard 的开发为构建这些新 VPN 提供了技术基础。