云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

大带宽_数据库索引设计与优化_免费6个月

小七 141 0

利用幂等性设计健壮、可预测的api

网络是不可靠的。我们都曾在连接Wi-Fi时遇到问题,或者突然有电话掉线。平均来说,连接我们服务器的网络比过去几英里内的用户级网络更可靠,比如蜂窝或家庭ISP,但是如果有足够的信息通过网络传输,它们仍然会以奇特的方式失败。总的来说,中断、路由问题和其他间歇性故障在统计上可能是不寻常的,但仍然会以某种环境背景速率一直发生。为了克服这种固有的不可靠环境,设计api和客户机是很重要的,这些api和客户机在发生故障时将是健壮的,并且可以预见地将复杂的集成带到一致的状态。让我们来看看实现这一点的几种方法。计划失败考虑任意两个节点之间的调用。可能会发生各种故障:当客户端尝试连接到服务器时,初始连接可能会失败。当服务器正在执行操作时,调用可能中途失败,从而使工作处于无定状态。调用可能会成功,但在服务器可以告诉其客户端之前,连接断开了。其中任何一个都会使提出请求的客户处于不确定的情况下。在某些情况下,失败是确定的,客户可以很肯定地知道,简单地重试是安全的。例如,甚至无法与服务器建立连接。不过,在其他许多情况下,从客户端的角度来看,操作的成功与否并不明确,而且它不知道重试操作是否安全。通过消息交换中途终止的连接就是这种情况的一个例子。这个问题是分布式系统的一个典型问题,当谈到这个意义上的"分布式系统"时,这个定义是宽泛的:只有两台计算机通过一个网络相互传递消息。即使是stripeapi和向它发出请求的另一个服务器也构成了一个分布式系统。充分利用幂等性解决由失败引起的分布式状态中不一致的最简单方法是实现服务器端点,使其成为幂等的,这意味着可以多次调用它们,同时保证副作用只发生一次。当客户机看到任何类型的错误时,它可以通过重试来确保自己的状态与服务器的状态一致,并且可以继续重试,直到可以验证成功为止。这完全解决了模糊故障的问题,因为客户机知道它可以使用一种简单的技术安全地处理任何故障。作为一个例子,考虑一个假设的DNS提供者的API调用,它使我们能够通过HTTP请求添加子域:卷曲https://example.com/domains/stripe.com/records/s3.stripe.com\-X输出\-d类型=CNAME\-d value="stripe.s3。亚马逊网站" \-深度ttl=3600创建记录所需的所有信息都包含在调用中,客户机可以多次调用它,这是非常安全的。如果服务器接收到一个由于域已经存在而发现是重复的调用,它将忽略该请求并使用成功的状态代码进行响应。根据HTTP语义,PUT和DELETE动词是幂等的,PUT动词特别表示目标资源应该被创建或完全替换为请求有效负载的内容(在现代RESTful术语中,修改将由补丁表示)。保证"精确一次"语义虽然围绕PUT和DELETE的固有幂等HTTP语义非常适合于许多API调用,但是如果我们有一个操作只需要调用一次而不再被调用呢?一个例子可能是,如果我们设计一个API端点来向客户收取费用;意外地调用它两次会导致客户被双重收费,这是非常糟糕的。这就是幂等键发挥作用的地方。当执行一个请求时,客户机生成一个唯一的ID来标识该操作,并将其与正常负载一起发送到服务器。服务器接收ID并将其与其端的请求状态相关联。如果客户机发现一个失败,它会用相同的ID重试请求,然后由服务器来决定如何处理它。如果我们考虑上述网络故障示例:在重试连接失败时,在第二个请求中,服务器将第一次看到该ID,并正常处理它。在操作中途出现故障时,服务器将接收工作并继续执行。具体的行为很大程度上取决于实现,但是如果之前的操作通过ACID数据库成功回滚,那么可以安全地批量重试。否则,状态将恢复并继续调用。在响应失败时(即操作成功执行,但客户端无法获得结果),服务器只需使用成功操作的缓存结果进行响应。Stripe API通过允许客户端通过特殊的幂等键头传入一个唯一值,从而在变化的端点上实现幂等键(在我们的例子中是POST下的任何内容),从而使客户端能够保证分布式操作的安全:卷曲https://api.stripe.com/v1/charges\-u sk_测试_bkokikjovbii2hlwgh4olfq2:\-H"幂等键:AGJ6FJMkGQIpHUTX"\-d金额=2000\-d货币=美元\-d description="Brandur收费"\-d客户=客户如果上述条带请求由于网络连接错误而失败,您可以使用相同的幂等密钥安全地重试,并且客户只需向其收费一次。做一个优秀的公民安全地处理故障非常重要,但除此之外,我们还建议以一种体贴的方式处理故障。当客户机发现网络操作失败时,很有可能是由于间歇性故障导致的,下次重试时该故障将消失。但是,也有可能是一个更严重的问题,它会变得更加棘手;例如,如果服务器正处于导致严重停机的事件中。操作的重试不仅不会进行,而且可能会导致进一步的降级。通常建议客户在看到错误时遵循类似于指数退避算法的方法。客户机在第一次失败时会阻塞一段短暂的初始等待时间,但随着操作继续失败,它将按比例等待2n,其中n是已发生的故障数。通过指数级后退,我们可以确保客户机不会重击宕机的服务器并导致问题。指数退避在计算机网络中有着悠久而有趣的历史。此外,加入随机因素也是个好主意。如果一个服务器的问题导致大量的客户机几乎同时失败,那么即使是在退出的情况下,它们的重试计划也可能非常紧密地一致,以至于重试将重击有问题的服务器。这就是所谓的雷鸣羊群问题。我们可以通过给每个客户机的等待时间添加一些随机的"抖动"来解决雷鸣般的群体问题。这将在所有客户端之间分配请求,并给服务器一些恢复的喘息空间。当服务器面临来自所有客户端的同时重试时,会出现雷鸣般的群体问题。striperuby库在失败时自动重试,使用一个幂等键,使用增加的退避时间和抖动。它的实现非常简单,您可以在GitHub上参考它来了解它的工作原理。编写健壮API的设计在构建既健壮又可预测的api时,考虑分布式系统中发生故障的可能性以及如何处理它是至关重要的。客户机上的重试逻辑和服务器上的幂等性是实现这一目标的有用技术,在任何技术堆栈中实现都相对简单。在设计客户机和API时,需要遵循以下几个核心原则:确保故障得到一致处理。让客户端对远程服务重试操作。不这样做可能会使数据处于不一致的状态,这将导致今后的问题。确保故障得到安全处理。使用幂等键和幂等键允许客户端传递唯一值并根据需要重试请求。确保以负责任的态度处理故障。使用指数退避和随机抖动等技术。请考虑可能陷入降级状态的服务器。喜欢这个帖子吗?加入条纹工程团队。视图洞口