【软件架构】Michael Perry关于不可变架构,CAP定理和CRDTs

简介: 【软件架构】Michael Perry关于不可变架构,CAP定理和CRDTs

查尔斯·哈姆伯与迈克尔·佩里谈论了他的书《永恒架构的艺术》。他们讨论的主题包括分布式计算的八个谬误:由L Peter Deutsch和Sun Microsystems的其他人提出的一组断言,描述了新加入分布式应用程序的程序员总是做出的错误假设。其他主题包括Pat Helland的论文“不变性改变一切”、Eric Brewer的CAP定理、最终一致性、位置无关身份和CRDT。他们还讨论了如何将Perry倡导的构建分布式系统的方法引入到需要与可变下游系统集成的真实企业应用程序中。

关键点

  • 以不变的方式构建系统意味着您可以将思考系统拓扑的想法与思考其行为和数据的想法分离开来。
  • 使这种方法发挥作用的核心是独立于位置的身份——不关心数据存储位置的身份。
  • Eric Brewer的CAP定理指出,对于分布式系统中需要的三个属性——一致性、可用性和分区容差——只有同时实现其中两个属性才有可能。在现实世界的分布式系统中,我们通常会放松一个约束,例如一致性。
  • CRDT,例如用于Google文档的treedoc,是一种数据类型,它允许我们通过一种优于最终一致性的一致性保证(称为强最终一致性)来放松一致性。
  • 不遵循不变性原则的一个副作用是系统可能不是幂等的。发件箱模式((outbox pattern )是我们将发生这种情况的可能性降至最低的一种方法。

介绍

查尔斯·亨伯:大家好,欢迎收看InfoQ播客。我是Charles Humble,该节目的共同主持人之一,也是云计算本土咨询公司Container Solutions的主编。我今天的客人是迈克尔·佩里。迈克尔是改善企业的首席顾问。他录制了许多Pluralsight课程,包括为企业构建分布式系统的密码学基础知识和模式。他最近还出版了一本书,书名为《不可变架构的艺术》,我发现这本书很吸引人,我也认为这是一本非常及时的书,思考我们如何构建分布式系统,以及我们如何才能做得更好。这就是我们今天要讨论的。迈克尔,欢迎收看InfoQ播客。

迈克尔·佩里:谢谢你,查尔斯。很高兴来到这里。

Pat Helland的“不变性改变一切”论文和分布式计算的八个谬误对您有多大影响?

查尔斯·亨伯:你在书中提到了几件事,我想我们也应该提到这些事,给听众一些背景知识。第一件是帕特·海兰德的论文,“不变性改变一切”“,由ACM于2016年出版。第二个是分布式计算的八个谬误,来自太阳微系统公司。我一定会链接到show notes中的这两个。我很感兴趣的是,当你在书中发展思想时,这两篇文章对你的思想有多大的影响。

迈克尔·佩里:是的,我想说这些谬论影响了我职业生涯的大部分时间。这些错误我已经犯过很多次了。所以当我开始写这本书的时候,我真的很想帮助人们认识到他们在自己的工作中犯了那些错误,当他们做出的假设正好落入这些谬误中时。然后当我看Pat Helland关于不变性的论文时,不变性改变了一切,他确实经历了一系列我们使用不变性来解决一些现实问题的地方,从硬盘如何组织到计算机网络如何工作。我发现不变性确实是在所有这些不同系统中解决这些谬误的关键因素

 

为什么我们默认为可变系统?

Charles Humble:就我自己而言,我知道当我考虑系统时,我自然会默认使用可变性,这可能是因为我的很多编程背景都是面向对象的语言,比如Java和C。但我怀疑这是一件很平常的事。我认为这是我们作为程序员通常做的事情,除非我们主要从事函数式编程。我很好奇你为什么这么认为?为什么我们默认为可变系统?

迈克尔·佩里:有两个原因。第一,这就是世界的运作方式。我们看到事情一直在变化。我们在软件中所做的很多工作都是通过对现实世界建模来解决问题。因此,如果我们用易变性来建模,这似乎是自然选择。另一方面是计算机的工作方式。计算机有可以更改其值的内存,它们有硬盘,我们可以用另一个文件的内容覆盖一个文件。所以他们的工作方式是多变的。因此,将这些可变工具应用于可变问题似乎是正确的选择。你为什么要绕道不变性,回来模拟一个可变的世界?这是违反直觉的。

什么是不变的架构?

Charles Humble:不变的架构是一个非常有趣的标题。我们已经说过,大多数程序员都是通过函数式编程来实现不变性的。既然如此,那么您如何将这些想法应用到架构中呢?什么是不变的架构?

MichaelPerry:从函数式编程的上下文开始,我们使用不变性来解释程序的行为,这有助于我们处理并发性之类的问题,这样我们就可以知道这就是价值所在。在我所看到的函数的范围内,没有其他我看不到的改变它的东西。现在,当我们从单个进程或一些内存中获取这些信息,并将其应用于分布式系统的行为时,现在我们谈论的是持久性存储,我们谈论的是在线消息,如果我们没有必要的工具来解释分布式系统的行为,那么,要实现我们真正想要实现的目标将非常困难。


比如,如果我问集群中的两个不同节点相同的问题,我会得到相同的答案吗?这是一种保证,我们称之为一致性,这非常重要。所以我们希望能够思考我什么时候才能达到一致性,一致性到底意味着什么?当涉及到建模问题时,通常了解系统如何处于特定状态与了解特定状态是什么一样重要。因此,记录这段历史有时真的很重要。历史就其本质而言是不可改变的。事情一旦发生,就已经发生了。你可以写下这一历史事实,它永远不会改变。因此,我认为将不变性带回我们的工具集中以解决分布式问题非常方便,非常有用。

Charles Humble:我们应该澄清听众可能存在的一些误解,我突然想到的一点是不可变架构和不可变基础设施之间的区别,因为不可变基础设施显然是一个在过去几年中被广泛使用的术语。你能给我们一个什么是它的定义,以及它是如何比较的吗?

迈克尔·佩里:不变的基础设施是一种描述虚拟机的实践,通常是所有的服务,它们所连接的网络,你说这就是状态,我不打算进去更新虚拟机的状态或更新网络配置的状态。相反,如果我想部署一个新的状态,我将并行部署它,传输所有流量,然后拆除原来的一个。因此,这是一个典型的想法,即将云资源视为商品,而不是你命名和关心的东西。


查尔斯·亨伯:另外一件事我们也许应该谈谈,因为如果你没有读过这本书,并且你不熟悉其中的思想,这可能是一个合理的假设,那就是当我们谈论不变的架构时,我们不是在谈论不能改变的架构,因为这显然是一个可怕的想法。

迈克尔·佩里:是的,那太糟糕了。我们讨论的不是不可变性的概念,并将其作为软件架构的核心,然后如何部署它,而是如果您愿意,可以将其部署在不可变的基础设施上。这是一个完全独立的问题。

你能给我们快速复习一下CAP定理吗?

查尔斯·亨伯:现在埃里克·布鲁尔的CAP定理支撑了书中的许多思想,以及我们在本次采访的其余部分将要讨论的许多内容。那么,如果听众从上次看这本书以来忘记了其中的一些细节,你能给他们一点复习吗?

迈克尔·佩里:这是埃里克·布鲁尔的猜想,给定一致性、可用性和分区容差,这是分布式系统中需要的三个属性,只有同时实现其中两个属性才有可能。所以一致性就是我刚才描述的。如果你问两个不同的节点相同的问题,你会得到相同的答案。可用性是指您将在合理的时间内得到答复。分区容忍度是指系统将继续维护这些问题,即使节点不能相互通信,网络中存在分区。所以CAP定理说你们只能选择两个。

你能帮我们解决两位将军的问题吗?

查尔斯·亨伯:你曾多次提到一致性问题,在书中你用两位将军的问题作为例证,我非常喜欢。你能不能也给不熟悉的听众一个简短的总结?

迈克尔·佩里:这是一个可以追溯到很久以前的一致性的例子。我不能声称自己是这本书的作者,但我发现它真的很吸引人。这个想法是这样的,你有几个将军在被围困的城市外领导军队,他们必须决定什么时候进攻。所以他们切断了补给线,并且派了侦察兵去调查,这座城市现在是否足够虚弱,可以进攻?如果只有一支军队进攻,那么进攻就会失败。他们必须同时进攻。所以他们必须同意,他们要么明天进攻,要么不进攻。因此,你的工作是制定一个协议,根据该协议,你可以保证,如果一支军队同意明天进攻,那么他们知道他们有一个保证,另一支军队也同意。


所以你可以这样想,“好吧,我要派一名侦察兵,或者我要派一名信使去见另一位将军,然后那名信使会说,‘我们明天要进攻’,然后我得到了保证。”不,你没有。你不知道那个信使真的到了另一个营地。他们可能被抓获了。因此,也许可以在你的协议中添加一个响应。所以我派了一个信使,说我们明天要攻击,我希望得到回应,然后在收到回应之前我不会攻击。那么,现在其他军队能知道他们要进攻了吗?因为他们只是要发送一条回应信息,他们不知道是否成功。所以你继续这个推理,最终你会发现没有任何协议可以保证你在某个特定的时间点达到一致性。

查尔斯·亨伯:据我所知,你能绕过这一点的唯一方法就是基本上放松一种或另一种约束。

迈克尔·佩里:是的,没错。所以如果你放松限制,“好吧,我们明天就要进攻。”现在没有最后期限了。只要需要,您可以继续协议。然后你也会放松那些你不会攻击的约束,除非你得到了对方的保证,因为这是问题的关键。你不能得到那个保证。因此,相反,我们会说我们将继续发送消息,直到我们都知道这个决定已经做出。因此,在这些宽松的约束下,你可以找到解决方案,而解决方案实际上非常简单。这些宽松的约束实际上映射到了最终一致性的概念。所以这给了我们一种方法,我们可以说明强一致性,如CAP定理所要求的,和最终的一致性,以及一些放松的约束之间的权衡。

真实世界中的最终一致性

Charles Humble:也许,在我职业生涯的早期,我就试图让这一点更具体一些,所以在20世纪90年代末,我想,我正在开发一个基本上是早期互联网银行应用程序的系统。因此,它将一个web前端放在一些背景为绿色屏幕大型机的东西上。我做的其中一件事是一个屏幕,可以向客户显示余额,这听起来似乎是一个非常小的问题,结果几乎是不可能的,因为您有待定的事务,各种大型机可能会为批处理作业每天同步一次,只是有时候批处理作业没有运行。你可能有来自提款机网络或信用卡机的交易,还有那些我们不知道或者我们知道会发生的事情,但它们仍然被保存在某处等等。

我想当时我不知道“最终一致性”这个词,但这基本上就是我们要处理的问题。因此,该项目的大部分时间都花在了与企业的对话上,即“什么是可接受的准确度,因为我们不能达到100%。那么,我们如何才能达到一个我们都能同意的程度,'是的,这很好'”,在我看来,这似乎说明了我们在谈论什么。


迈克尔·佩里:是的,这是一个非常好的真实世界的例子,正好说明了我们正在讨论的问题。因此,人们可能会认为,“好吧,既然两位将军的问题是,如果你可以在不放弃可用性的情况下拥有一个网络分区,那么就不可能实现强一致性”,那么你可能会想,“好吧,像ATM这样的东西不可能工作,但它们确实工作。那么我们如何解决这个问题呢?”我们通过在业务领域中加入这些放松的约束来解决这个问题。因此,是的,我们允许客户提取一些钱,即使我们不能保证他们的余额超过20美元,例如。我们仍然允许该事务,因为我们知道我们已经从问题域本身获得了一些补偿。

查尔斯·亨伯:问题是,如果我的时间足够快和幸运的话,我可能可以从一台提款机中提款,然后跑到另一台提款机中进行另一次提款,即使我的账户不允许,我最终也会透支,但如果企业说,“好吧,没关系”,那就没关系了。

迈克尔·佩里:是的。如果他们能将其转化为收入流,那就更好了。

位置独立身份的目的是什么?

查尔斯·亨伯:当然,是的。寄给你后者或其他东西,我们要收你20英镑。因此,在书中的一章中,你谈到了独立于位置的身份。再一次,我发现这真的很有趣。那么,这样做的目的是什么?

迈克尔·佩里:我认为这是使这种架构发挥作用的基石之一。通常,如果我们使用的是关系数据库,我们将有一个自动递增的ID作为列之一。因此,我们将使用插入时生成的ID作为存储的记录的标识。该标识仅在特定数据库集群中有效。所以它与一个特定的位置有关。您可以想象几个不同的场景,其中相同的实体、相同的对象在不同的位置具有不同的标识。如果存储脱机备份,我们可能只是对其执行相同的SQL语句,但随后生成不同的ID。或者我们可能有两个不同的副本,它们都接受写操作,因此它们都可能分配相同的ID,但分配两个不同的对象。

因此,使用与某个位置相关的身份是给我们带来麻烦的原因之一。这让我们陷入了一个糟糕的境地。所以我在书中探讨的是一组我们可以选择的独立于位置的身份。他们不关心数据存储在哪里。一个很好的例子是散列。因此,您获取您试图存储的值,假设它是一幅图像,一张照片,然后您将计算一个SHA-512散列。不管是谁计算,哈希值都是一样的。因此,如果你使用它作为照片的标识,而不是文件名,那么该标识将是独立于位置的。因此,通过使用独立于位置的标识,您可以让分布式系统中的不同机器相互谈论对象,并知道它们在谈论同一件事情。

Charles Humble:鉴于位置独立性是不变架构的一个特性,那么您如何保证两个节点最终会得出相同的结论?

迈克尔·佩里:这是一些真正优秀的数学论文发挥作用的地方。因此,如果你有一个基于收集不可变记录的系统,你必须对你收集的记录有一些保证,以确保每个人都以同样的方式解释它们。因此,其中一个保证与这些事件的顺序,这些消息的顺序有关。如果你必须以相同的顺序播放所有消息,以使两个节点获得相同的结果,那么这些消息就不是我们所说的相互交换的,就像代数中的交换属性,A+B等于B+A。因此如果我们可以保证,如果我以不同的顺序接收消息,我们仍然计算相同的结果,然后我们可以说我们的消息处理程序正在进行通信。

因此,我们现在可以将其应用到分布式系统中,如果我们提出一个与plus类似的操作,它是一个交换操作,并且只使用该操作来计算当前状态,那么现在我们可以在该操作的基础上构建分布式系统,并免费获得该保证。所以我喜欢使用的操作是set union。如果我收到两个不同的对象,把它们放进集合中,然后我把这些集合合并在一起,我会得到一个包含这两个对象的集合,其他人可以以不同的顺序接收它们,合并它们,它们仍然会得到相同的集合,因为集合不知道事物在集合中出现的顺序。现在,如果你能在集合并集运算的基础上构建你的整个系统,那么你真的取得了进展。你可以有一些强有力的保证最终达到同样的状态。

你能给我们举一两个例子,说明书中的一些思想在现实世界中的应用吗?

Charles Humble:为了让这更具体一点,你能给我们举一两个例子,说明书中的一些思想在现实世界中的应用,也许是你所从事的应用中的应用吗?

迈克尔·佩里:例如,几年前我设计的一个系统是用于执法的。因此,随着时间的推移,一个案例发生了不同的变化。所以你可能会想,“好吧,改变一个案例。你说的是一些变异的案例。”但我们实际上收集的是变化本身,这些变化是不变的。所以改变说,“好吧,这就是我们正在讨论的情况,现在确定这个情况,并以独立于位置的方式进行,这样每个人都知道你正在谈论的是哪一个。然后是谁做出了改变?最重要的是,他们在做出改变时有哪些信息?”所以现在这必须在将来的某个时候得到管理员的批准。因此,由于这是执法信息和有关现行案件的信息,我们必须确切地知道这些信息来自何处。我们必须知道这是经过核实的。

因此,在核实这些信息的同时,其他执法人员看到的案件中没有这些新信息。因此,他们可以进行自己的编辑,从而生成有关案例更改的新的不变事实。因此,最终可能会有两名不同的官员对案件的同一部分进行更改,但他们中的任何一人都尚未获得批准。所以两个人都不知道另一个。所以如果你把它放在一个有向无环图中,现在你会有一个图,其中这两个节点没有相互引用。他们不知道另一个存在。现在你把这组音符的集合并起来,你会得到一个有两片叶子的图。它有两个地方,你可以说,“这是那个图的终点。”

现在看到这个形状,管理员可以看到,“哦,好吧,这里有一个并发编辑”,他们可以选择批准一个,拒绝另一个,或者他们可以选择合并这两个信息本身,从而产生第三个编辑事实,现在与前两个有因果关系。所以它指向另外两个,创建一个现在只有一个叶节点的图。这是一个真实的例子,说明了我们是如何将不变性的思想,集合联合的思想引入到问题领域的,这不是为了解决分布式系统的任何问题,而是为了解决实际领域的问题。


Charles Humble:在这本书中,你还使用了Git和Docker的例子,以及区块链作为以类似方式工作的系统的例子,这些系统展示了不变架构系统的一些相同特征。所以你能不能拿一个,用它来扩展我们的一些想法?

迈克尔·佩里:事实上,我刚才提到的执法应用程序的例子,实际上非常类似于我们在团队中工作时一直在软件中解决的问题,就是我们在不知道其他人同时进行的更改的情况下更改源代码。它们可能没有经过拉请求过程,因此它们不是主分支的一部分,因此它们不是我们当前正在做的工作的前身。但我们能够在版本控制系统中记录这一点,因为我们有父提交的提交。所以提交是一个不可变的记录,指向历史上的一条记录,它说,“好的,这个新的事实是在了解以前的事实的基础上,根据以前的事实创建的。”

还有另一个例子,我们在使用不变性,我们在使用这个想法,合并有向无环图,以解决一个实际问题。作为开发人员,这是我们更熟悉的一个。事实上,它也解决了分布式系统的问题,因为我可以脱机工作。我可以让我的机器与远程设备断开连接,我仍然可以非常高效地工作。我知道,当我重新联机时,我最终会与远程设备和我团队的其他成员保持一致。

CRDT如何融入到图片中?

Charles Humble:让我们来思考一下数据类型,你在书中谈到了CRDT,这是我的InfoQ同事韦斯·赖斯(Wes Reisz)去年在播客的一集上与彼得·博根(Peter Bourgon)谈到的一个话题。因此,我将在节目说明中链接到这一点。但是,为了把我们大家联系在一起,你能谈谈CRDT以及它们如何融入故事中吗?

迈克尔·佩里一种无冲突的复制数据类型,相当多。但它是一种数据类型,所以你可能会想到链表,你可能会想到有向无环图。这是一组数据类型为operations的状态,它在内部执行的操作就像更新或合并一样。那么这两件事意味着什么呢?更新是为了在CRDT中记录一些新信息而执行的操作,而合并是当我们了解该CRDT的其他系统副本时将执行的操作。因此,如果我们在一个节点上工作,用户正在交互,然后他们按下一个按钮,他们想要执行一个操作,我们将在CRDT的副本上执行更新。然后,当我们与服务器或对等方交谈时,这就是我们要与其他人合并的地方。

因此,CRDT只是一组通用规则,用于我们如何保证数据结构,以确保它最终在所有不同副本中达到一致状态。CRDT非常令人兴奋,因为它们有一个比最终一致性更好的一致性保证。这叫做强最终一致性。这是一种保证,CRDT在收到相同的更新后将达到一致的状态,而不一定是在他们都有机会相互交谈并达成共识时,例如,使用Paxos算法。因此,一旦所有节点完成所有更新,它们就处于相同的状态。对于最终的一致性来说,这是一个非常有力的保证,我发现这对我所有工作的基础非常有用。

谷歌文档中如何使用CRDT?

Charles Humble:CRDT已经在一些非常重要的知名应用中使用。我想最著名的可能是谷歌文档。因此他们有一种特殊的CRDT数据类型,称之为Treedoc,Treedoc用于处理多个用户编辑同一文档时发生的同步。那么,你能谈谈这一点吗?这与你自己在该领域的工作相比如何?

迈克尔·佩里:是的,我想说的是,像Treedoc这样的东西都是非常具体的CRDT,旨在解决特定的问题。因此Treedoc解决了文档的协作编辑问题,而且协作可以是实时的,就像我们在Google Docs中看到的那样,它可以离线,并在文档上线后支持合并。它们提供的最终一致性保证是,最终每个人都会在屏幕上看到相同的文本。你不会看到一些人先看一段再看另一段,而有些人看的顺序相反。因此,Treedoc和其他CRDT是针对其特定问题开发的。我的目标是开发一种更通用的CRDT。我提出的一个例子是,合并操作是一个集合并集,它所讨论的状态是一个有向无环图。因此,如果可以执行两个有向无环图的集合并集,那么可以保证执行这些操作的任意两个节点将实现相同的图。


现在有一个CRDT的另一个方面,我以前没有提到过。这是一个投影函数。有一种方法,你可以采取内部状态和投影到应用程序可以看到的地方。因此,在Treedoc的情况下,投影函数为您提供了一个充满文本的屏幕,但内部状态不仅仅是文本。仅仅文本中没有足够的信息来保证您可以合并它。同样地,在这个使用有向无环图的应用程序中,投影函数是如何查询一个图,以了解应用程序的当前状态?可能会有很多图形提供相同的当前状态,因为在用户执行该操作时,信息对用户是隐藏的。所以人们无法看到所有发生的事情的全部历史。他们只能看到最终结果是什么。

作为一名应用程序开发人员,如果你能给我一组历史事实,我可以把它们组织成一个有向无环图,你给我一个投影函数,告诉我如何向你的用户显示这个有向无环图,那么这就是我所需要的,我可以解决最终一致性很强的问题,我可以在节点之间同步数据,我可以脱机工作,我可以存储脱机发生的事情,然后将它们排队等待稍后发送到服务器。因此,通过以不同的方式描述问题,您可以立即获得所有这些功能。

您认为采用这种方法构建分布式系统的主要好处是什么?

Charles Humble:提高一个级别,您认为采用这种方法构建分布式系统的主要好处是什么?

迈克尔·佩里:我认为,主要的好处是,您可以将思考系统拓扑的想法与思考其行为和数据的想法分离开来。很多时候,当我们在构建应用程序时,我们将如何将其存储到文件、如何设计消息、如何订阅队列以及所有这些拓扑思想融合在一起,我们正在解决这些业务问题。那么,我如何设计一条消息来表示业务中的这一特定操作呢?因此,您最终必须为构建的每个应用程序解决分布式系统中的相同问题。因此,如果你能将它们解耦,你可以说,“好吧,在这一点上,我试图解决一个分布式系统的问题,但现在我考虑的是拓扑,现在只考虑问题域,”那么你就更容易对问题域进行推理,知道你能做什么和不能做什么,让它更具体一点。

在你的问题域中,你可能会遇到一个问题,那就是你想为某个特定的时间预订一个房间。所以当时只有一次会议可以在那个房间举行。因此,这是一个很难解决的问题。所以你可以用拓扑来解决这个问题,比如说,“好吧,有一台机器做出了这个决定,如果我收到另一个预订房间的请求,那台机器就会锁定到那个记录并拒绝第二个请求。”所以拓扑瓶颈的想法,锁定的想法,这是你问题的一部分。那么预订房间的欲望是你问题的另一部分。

那么,你能做些什么呢?把这些不可变架构的概念拿出来,说他们允许我做什么保证,他们不允许我做什么保证?你可以通过这一点进行推理,并意识到没有一个通用的解决方案来预订房间,并保证只有一个人在那个特定的时间预订了房间。在这一点上,你可以说,“好的,在这一点上,我需要引入一个拓扑解决方案来解决这个问题。”然后,所有不依赖于这些强约束类型的问题,以及所有不依赖于这些强约束的问题,都可以用更一般的方法来解决。

如何开始向企业应用程序引入一种不变的方法?

Charles Humble:现在,如果我决定在典型的大型企业应用程序中采用这种方法,我所预见的挑战是,我将与下游系统交谈,这些系统可能是我无法控制的,它们不会遵循您提倡的那种不变的方法。所以我很好奇我该怎么办。例如,您在书中提到了发件箱模式,显然这是我们将这些概念引入典型企业环境的一种方法。所以,也许你可以更笼统地谈一谈,如果听众觉得这些做法适合他们的特定问题,你会如何建议他们采用这些做法?

迈克尔·佩里:这总是最难的问题。所以其中一个解决方案,发件箱模式,你刚才提到的,是一种方式,我可以在我的不可变架构中学习新的不可变事实,我可以与不遵循不可变原则的外部系统交谈。因此,不遵循不变性原则的一个副作用是,这个外部系统可能不是幂等的。这是一个奇特的数学单词,意思是如果我发送两次相同的消息,它可能会复制效果。因此,如果我使用HTTP POST,然后它返回它刚刚发布的内容的URL,如果我没有收到第一个,我可能会尝试再次发布,它可能会插入一条新记录,生成一个新ID,然后返回一个新URL,所以这只是重复了工作。

所以发件箱模式是一种方法,我们不能保证我们解决幂等问题,而只是最小化它发生的概率。这是一个想法,首先,在我们的系统中引入一个拓扑瓶颈。所以这只是一种说法,我们只会有一台机器与该API进行通信。我们不会尝试从不同的机器同时与API对话。其次,一台机器将记录发送给第三方的所有信息。现在,journal可以将API请求链接回不可变系统中的事实,而在可能需要调用此API之前,让我调用API,再次检查,我仍然需要调用API。让我调用API。我可能不知道第一个电话是否还在等着。所以这本日记至少能帮助我们了解这一点。

它不允许我们跟踪消息是否传到了另一边,所以我们仍然有可能他们听到了第一条消息,但是我们超时了,然后他们收到了一条重复的消息。它至少使窗口最小化了一点。这是本书中讨论的模式之一,关于如何与尚未遵循不变性实践的第三方系统集成,但希望在很多人阅读本书之后,这将不再是一个问题,一切都将是不变性的,这将是一个美好的世界。

查尔斯·亨伯:希望如此。如果听众想了解更多,你会建议他们下一步去哪里?

迈克尔·佩里:从immutablearchitecture.com开始。在这个网站上,你可以直接从Apress或Amazon上找到购买这本书的链接,你也可以找到与我联系的方法,了解有关不可变架构的知识,以及你可以与我一起参与书籍学习的方法。

相关文章
|
6月前
|
存储 监控 微服务
微服务和单体架构是两种不同的软件架构风格
微服务和单体架构是两种不同的软件架构风格
81 1
|
存储 人工智能 架构师
ChatGPT 与软件架构 (4) - 架构师提示工程指南
ChatGPT 与软件架构 (4) - 架构师提示工程指南
138 0
|
存储 人工智能 架构师
ChatGPT 与软件架构 (2) - 基于 Obsidian 和 GPT 实现解决方案架构自动化
ChatGPT 与软件架构 (2) - 基于 Obsidian 和 GPT 实现解决方案架构自动化
202 0
|
4月前
|
人工智能 供应链 架构师
软件架构一致性问题之Serverless架构处理架构一致性问题如何解决
软件架构一致性问题之Serverless架构处理架构一致性问题如何解决
54 2
|
6月前
|
存储 监控 微服务
微服务和单体架构是两种不同的软件架构风格,每种都有其自身的优缺点
【1月更文挑战第1天】微服务和单体架构是两种不同的软件架构风格,每种都有其自身的优缺点
113 0
|
6月前
|
架构师 微服务
什么是软件架构?架构的本质是什么?
定义 ”架构是什么“ 是件非常困难的事情,不同的组织对于软件架构有不同的定义,每个人心中也有自身对于系统架构定义的认知。就好比我们无法百分之百表述模型而只能产出模型不同维度的视图,对架构进行完备的定义是不可能的。
134 4
|
6月前
|
前端开发 Oracle 安全
软件架构设计 C/S与B/S架构的区别
C/S是Client/Server的缩写。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统,如Oracle或SQLServer。
75 0
|
6月前
|
缓存 监控 Java
DP读书:鲲鹏处理器 架构与编程(十四)ACPI与软件架构具体调优
DP读书:鲲鹏处理器 架构与编程(十四)ACPI与软件架构具体调优
155 1
|
6月前
|
安全 前端开发 Linux
DP读书:鲲鹏处理器 架构与编程(十一)鲲鹏生态软件架构 AND 硬件特定软件
DP读书:鲲鹏处理器 架构与编程(十一)鲲鹏生态软件架构 AND 硬件特定软件
81 0
|
人工智能 监控 架构师
ChatGPT 与软件架构 (3) - 软件架构提示工程
ChatGPT 与软件架构 (3) - 软件架构提示工程
139 0