JSON-RPC? 采取棘手的休息

JSON-RPC? 采取棘手的休息

我确信这个标题引起了良好的反应 - “好吧,又开始了……”但是让我用 5 到 10 分钟来吸引您的注意力,我会尽力不辜负您的期望。

文章的结构如下:采取一种刻板印象的陈述,并揭示这种刻板印象出现的“本质”。 我希望这能让您从一个新的角度来看待项目中数据交换范式的选择。

为了清楚什么是RPC,我建议考虑一下标准 JSON-RPC 2.0。 对于 REST 来说,没有明确性。 但事实不应该如此。 关于 REST 您需要了解的一切 - 它与 HTTP.

RPC 请求更快、更高效,因为它们允许您发出批量请求。

要点是,在 RPC 中,您可以在一个请求中同时调用多个过程。 例如,创建一个用户,为他添加头像,并在同一请求中为他订阅一些主题。 只要一求,多大的好处!

事实上,如果您只有一个后端节点,那么批量请求看起来会更快。 因为三个 REST 请求将需要一个节点三倍的资源来建立连接。

JSON-RPC? 采取棘手的休息

请注意,在 REST 情况下,第一个请求必须返回用户 ID,以便发出后续请求。 这也会对整体结果产生负面影响。

但此类基础设施只能在内部解决方案和企业中找到。 作为最后的手段,在小型 WEB 项目中。 但成熟的 WEB 解决方案,甚至那些称为 HighLoad 的解决方案,都不值得构建。 他们的基础设施必须满足高可用性和负载的标准。 而情况正在发生变化。

JSON-RPC? 采取棘手的休息

同一场景下的基础设施活动通道用绿色标记。 请注意 RPC 现在的行为方式。 该请求仅使用从平衡器到后端的一侧的基础设施。 虽然 REST 在第一个请求中仍然会丢失,但它弥补了使用整个基础设施损失的时间。

在脚本中输入的不是两个丰富请求,而是五个或十个……以及“现在谁赢了?”这个问题的答案就足够了。 变得不清楚。

我建议从更广泛的角度来看待这个问题。 该图显示了基础设施通道的使用方式,但基础设施并不限于通道。 高负载基础设施的一个重要组成部分是缓存。 现在让我们获得某种用户工件。 反复。 假设是 32 次。

JSON-RPC? 采取棘手的休息

了解 RPC 基础设施如何显着改进以满足高负载的需求。 问题是,与 RPC 不同,REST 使用了 HTTP 协议的全部功能。 在上图中,这种能力是通过请求方法——GET 来实现的。

HTTP 方法除其他外还具有缓存策略。 您可以在以下位置的文档中找到它们: HTTP。 对于RPC,使用的是POST请求,不被认为是幂等的,即重复重复相同的POST请求可能会返回不同的结果(例如,每次发送评论后,都会出现该评论的另一个副本)().

因此,RPC 无法有效地使用基础设施缓存。 这导致需要“导入”软件缓存。 该图显示了 Redis 的这一角色。 反过来,软件缓存要求开发人员添加额外的代码层并在架构中进行显着的更改。

现在让我们计算一下在所考虑的基础设施中 REST 和 RPC“产生”了多少个请求?

请求
收件箱
到后端
到数据库管理系统
到软缓存(Redis)
TOTAL

REST的
1 / 32 *
1
1
0
3 / 35

RPC的
32
32
1
31
96

[*] 在最好的情况下(如果使用本地缓存)1 个请求(一个!),在最坏的情况下 32 个传入请求。

与第一个方案相比,差异是惊人的。 现在 REST 的好处变得显而易见。 但我建议不要就此止步。 开发的基础设施包括 CDN。 通常它还可以解决对抗 DDoS 和 DoS 攻击的问题。 我们得到:

JSON-RPC? 采取棘手的休息

这就是 RPC 的情况变得非常糟糕的地方。 RPC 根本无法将工作负载委托给 CDN。 我们只能依靠系统来反击攻击。

到这里就可以结束了吗? 再说一次,不。 如上所述,HTTP 方法有其自身的“魔力”。 GET 方法在互联网上广泛使用也不是没有原因的。 请注意,此方法能够访问一段内容,能够设置基础结构元素在控制权转移到代码之前可以解释的条件,等等。 所有这些使您能够创建灵活、可管理的基础架构,可以处理真正大的请求流。 但在 RPC 中,这个方法...被忽略。

那么为什么批量请求(RPC)更快的神话如此持久? 就我个人而言,在我看来,大多数项目根本没有达到 REST 能够发挥其优势的开发水平。 而且,在小项目中,他更愿意展现自己的弱点。

选择 REST 还是 RPC 并不是项目中个人的自愿选择。 这个选择必须满足项目的要求。 如果一个项目能够从 REST 中榨取所有它真正能榨取的东西,并且它确实需要它,那么 REST 将是一个很好的选择。

但是,如果为了获得 REST 的所有好处,您需要为项目聘请 DevOps 专家来快速扩展基础设施、聘请管理员来管理基础设施、聘请架构师来设计 WEB 服务的所有层……以及项目,同时,每天卖三包人造黄油...我会坚持使用RPC,因为... 这个协议更加实用。 它不需要深入了解缓存和基础设施的工作原理,而是让开发人员专注于对其所需过程的简单且易于理解的调用。 生意会很愉快。

RPC 请求更可靠,因为它们可以在单个事务中执行批量请求

RPC 的这个特性是一个明显的优势,因为保持数据库的一致性很容易。 但对于 REST,它会变得越来越复杂。 请求到达不同后端节点时可能不一致。

REST 的这一“缺点”是其上述优点的另一面——有效利用所有基础设施资源的能力。 如果基础设施设计得不好,更何况项目的架构,特别是数据库设计得不好,那真是一个很大的痛苦。

但批量请求真的像看起来那么可靠吗? 让我们看一个案例:我们创建一个用户,用一些描述丰富他的个人资料,并向他发送一条包含秘密的短信以完成注册。 那些。 一批请求中的三个调用。

JSON-RPC? 采取棘手的休息

让我们看一下图表。 它提供了具有高可用性元素的基础架构。 与短信网关有两个独立的通信通道。 但是……我们看到了什么? 发送短信时,出现错误503——服务暂时不可用。 因为短信发送被打包在批量请求中,那么整个请求必须回滚。 DBMS 中的操作被取消。 客户端收到错误。

下一个尝试是彩票。 要么请求会再次命中同一个节点并再次返回错误,要么你很幸运,它将被执行。 但最重要的是,至少有一次我们的基础设施已经徒劳无功。 有负载,但没有利润。

好吧,让我们想象一下,当请求可以部分成功完成时,我们已经竭尽全力(!)并仔细考虑了该选项。 我们会尝试在一段时间间隔后再次完成剩下的部分(哪一个?前面决定吗?)。 但抽奖还是一样。 发送 SMS 的请求有 50/50 的机会再次失败。

同意,从客户端来看,该服务似乎并不像我们希望的那样可靠...... REST 怎么样?

JSON-RPC? 采取棘手的休息

REST 再次使用 HTTP 的魔力,但现在带有响应代码。 当短信网关出现503错误时,后端会向均衡器广播该错误。 平衡器收到此错误,并且在不中断与客户端的连接的情况下,将请求发送到另一个节点,该节点成功处理了该请求。 那些。 客户收到了预期的结果,基础设施证实了其“高度可访问”的崇高称号。 用户很高兴。

再说一遍,这还不是全部。 平衡器不仅仅收到响应代码 503。响应时,根据标准,建议为此代码提供“Retry-After”标头。 标头向平衡器明确表明,在指定时间内不值得干扰该路由上的该节点。 而接下来发送短信的请求将直接发送到短信网关没有问题的节点。

正如我们所看到的,JSON-RPC 的可靠性被高估了。 事实上,在数据库中组织一致性更容易。 但在这种情况下,牺牲的将是整个系统的可靠性。

结论与上一个大体相似。 当基础设施很简单时,JSON-RPC 的明显性绝对是一个优势。 如果项目涉及高负载的高可用性,REST 看起来是一个更正确但更复杂的解决方案。

REST 的进入门槛较低

我想,上面的分析打破了人们对RPC的刻板印象,清楚地表明,进入REST的门槛无疑比进入RPC要高。 这是因为需要深入了解 HTTP 的工作原理,以及需要对可以而且应该在 WEB 项目中使用的现有基础设施元素有足够的了解。

那么为什么很多人认为REST会更简单呢? 我个人的观点是,这种表面上的简单性来自于 REST 本身的表现。 那些。 REST 不是一个协议,而是一个概念...REST 没有标准,有一些准则...REST 并不比 HTTP 更复杂。 明显的自由和无政府状态吸引着“自由艺术家”。

当然,REST 并不比 HTTP 复杂。 但 HTTP 本身是一个设计良好的协议,几十年来已经证明了它的价值。 如果对HTTP本身没有深入的了解,那么REST是无法判断的。

但对于 RPC - 你可以。 拿它的规格就够了。 那么你需要 愚蠢的 JSON-RPC? 或者 REST 仍然很棘手? 你决定。

我真诚地希望我没有浪费您的时间。

来源: habr.com

添加评论