webhook 和 API:你了解吗

news2024/11/15 9:14:15

Webhooks 是许多 API 的补充。通过设置 webhook 系统,系统 B 可以注册接收有关系统 A 某些更改的通知。当更改发生时,系统 A 推送 更改到系统 B,通常是以发出 HTTP POST 请求的形式。

Webhooks 旨在消除或减少不断轮询数据的需要。但根据我的经验,webhooks 带来了一些挑战。

通常,您不能单靠 webhooks 来保持两个系统的一致性。我参与过的每一个集成项目最终都意识到这一点,并通过轮询增强了 webhooks。这是由于几个问题领域。

首先,当您的系统宕机时存在风险。是的,发送者通常会用某种指数退避重试未送达的 webhooks。但保证往往是宽松或不明确的。而且系统从灾难中恢复后,最不需要的可能就是处理积压的 webhooks 大量任务。

其次,webhooks 是短暂的。它们太容易处理不当或丢失。如果您在部署代码更改后意识到您输入了一个错误的 JSON 字段,并且正在将 null 插入到您的数据库中,那么您无法回放 webhooks。或者,您可能会在 webhook 请求之外处理部分 webhook 处理流程——比如数据库插入。但那样您就冒着失败并丢失 webhook 的风险。

为了缓解这两个问题,许多开发人员最终将 webhooks 缓存在像 Kafka 这样的消息总线系统上,这感觉像是一个笨重的妥协。

考虑两方之间复杂的 webhook 管道结构:

我们在发送端和接收端各有一个消息总线。复杂性显而易见,而且可能出问题的阶段很多。例如:在接收端,即使您的系统运行良好,您仍然可能受到发送者可交付性失败的影响。如果发送者的队列开始经历背压,webhook 事件将被推迟,而您可能很难知道这种滑移正在发生。

增加复杂性的是,两者之间的安全层通常是某种 HTTP 请求签名协议,如 HMAC。这很稳固且减轻了管理秘密的负担。但对于您的普通开发人员来说,这也不太熟悉,因此更容易头疼和出错。(HTTP 请求 签名和验证是那些任务之一,我觉得一个人做得不够频繁,以至于永远不会完全记住。)

因此,不仅仅是 webhooks 使您最终面临不一致,它们对每个人来说也是更多的工作。

那么我们还能用什么来保持两个系统的同步呢?

/events 接口

要寻找保持两个数据集和谐的灵感,我们不妨看看数据库。考虑 Postgres 的复制插槽:您为每个从数据库创建一个复制插槽,从数据库订阅该复制插槽以获取更新。

两个关键组成部分是:

  • 主数据库保持最近变更的日志
  • 主数据库保持一个游标,跟踪每个从数据库在更改日志中的位置

如果从数据库宕机,当它恢复时,可以自由地翻阅历史记录。没有队列,也没有在每端尝试像接力棒一样传递事件的工人。

API 也可以遵循这种模型。以 Stripe 为例。他们有一个 /events 接口,包含过去 30 天内对 Stripe 帐户进行的所有创建、更新和删除操作。每个事件对象都包含所操作实体的完整有效载荷。这里有一个事件的示例,针对一个 subscription 对象:

 

{ "id": "evt_1J7rE6DXGuvRIWUJM7m6q5ds", "object": "event", "created": 1625012666, "data": { "object": { "id": "sub_JgFEscIjO0YEHN", "object": "subscription", "canceled_at": 1625012666, "customer": "cus_Jff7uEN4dVIeMQ", "items": { "object": "list", "data": [ // ... ], "url":"/v1/subscription_items?subscription=sub_JgFEscIjO0YEHN" }, "start_date": 1623826800, "status": "canceled", } }, "type": "customer.subscription.deleted" }

一些重要的特质:

  • 每个事件有一个 type,告诉我们这个事件是什么。在这个案例中,我们看到一个客户的订阅已被删除。因为包含了完整的订阅有效载荷,我们可以更新我们的数据库以反映字段如 canceled_at 和它的新 status 为 canceled
  • 每个嵌入对象包含一个 object 字段,所以我们可以轻松地提取和解析它们。
  • 事件对象大量嵌入子对象,让我们全面了解所有变化,无需轮询 API

因此,我们可以轮询 /events 来保持事物的最新状态,而不是监听 webhooks。我们只需在本地保持一个游标,我们在请求中使用它来指示给 Stripe 我们已经看到了哪些事件。

优势:

  • 如果我们宕机,我们不用担心错过 webhooks。当我们恢复时,我们可以自己的步调赶上。
  • 如果我们部署了一个错误地处理事件的错误,不用担心。我们可以部署修复,并为 /events 倒带游标,它将回放它们。
  • 我们端不需要消息总线。
  • 我们不必担心 Stripe 的 webhook 发送者延迟交付。速度掌握在我们手中。我们与最新数据之间的唯一障碍是 Stripe 在 API 层面所做的任何缓存(看起来是没有的)。
  • 我们使用简单的基于令牌的身份验证方案。
  • 我们拉取和处理事件的方式与我们处理任何其他端点的方式相同。我们可以重用许多相同的 API 请求/处理代码。

在生产者端,为了支持 /events,您需要添加监控创建/更新/删除的同样仪式,就像您会为 webhooks 使用的那样。除了,您不需要构建交付管道,您只需要将记录插入到一个仅追加的数据库表中。

在消费者端,您将需要设置一些轮询基础设施。这比如说,一个处理一切的基本 webhook 处理端点需要更多的基础工作。但是,我敢打赌一个像样的轮询系统构建起来并不比一个健壮的 webhook 处理系统难,例如,一个带有消息总线的系统。而且您得到了更好的一致性保证。

使 /events 更好

在 /events 接口中有一个明显的低效之处:为了尽可能保持实时性,您必须非常频繁地轮询。我们每个帐户每 500 毫秒轮询一次 Stripe /events 端点,并考虑将其减半。

这些请求很轻,因为对于大多数活跃的 Stripe 帐户来说,响应往往是空的。但作为程序员,我们不禁想寻找一种更有效的方式。

对于 Stripe 和其他 API 平台来说,一个创意:支持长轮询!

在长期被遗忘的长轮询艺术中,客户端发出标准的 HTTP 请求。如果服务器没有新的信息需要传递给客户端,服务器将请求保持开放,直到有新的信息要传递。

在我们与 Stripe 的集成中,如果我们可以请求 /events 并指出我们希望进行长轮询,那会很好。根据我们发送的游标,如果有新事件 Stripe 将立即返回这些事件。但如果没有,Stripe 可以保持请求开放,直到创建了新事件。当请求完成时,我们只需重新打开它并重复循环。这不仅意味着我们可以尽快获得事件,还可以减少总体网络流量。

长轮询相对于 websockets 的优势在于代码重用和简单性。大多数集成本来就涉及某种形式的轮询,无论您是在回填数据还是重播错误处理的事件。能够通过单一参数调整从例如回填切换到实时监听新事件的能力是一个巨大的胜利。

我应该使用哪个?

对于 API 消费者来说,如果您幸运地有选择使用轮询 /events 或使用 webhooks 的选择,那么该选择使用哪个主要取决于您的一致性需求。Webhooks 可以更快地开始使用,特别是如果您只关心几个 API 对象。对于某些工作流程,如果 webhooks 被丢弃也没关系,比如您正在向 Slack 频道发布“新订阅者”公告。

但随着集成的重要性增长以及确保不丢失任何东西的需求出现,我们认为轮询 /events 很难被超越。

对于 API 生产者来说,支持 /events 不仅是给您的 API 消费者的一份大礼。/events 可以轻松成为提供 webhooks 的跳板。您的 events 表可以作为您的 webhook 发送者的出站工作的“队列”。事实上,/events 可以解锁急需的 webhook 功能,比如允许您的 webhook 消费者重放或重置其 webhook 订阅的位置。

  • 源于:Give me /events, not webhooks

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1677755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何购买RAKsmart的国外高防服务器?

随着互联网的快速发展,网络安全问题日益凸显,特别是对于拥有在线业务的企业或个人来说,选择一款高防服务器显得尤为关键。美国RAKsmart作为知名的服务器提供商,其高防服务器因其卓越的性能和安全性,受到了广大用户的青…

一步一步带你做网络工程

网络工程怎么做 一、网络设备交换机的应用: 要求:在此接入交换机S3700,上划分两个vlan,vlan10和vlan20分别有两个PC,按拓扑图完成要求: 划分vlan添加端口 sys [Huawei]sys S1 [S1]undo in e [S1]undo t…

【全开源】JAVA同城圈子达人交友系统源码支持微信小程序+微信公众号+H5+APP

同城达人 精准匹配:系统通过用户填写的个人信息和兴趣爱好,运用智能算法进行精准匹配,推荐合适的同城朋友。多种互动方式:提供在线聊天、语音通话、视频交流等多种互动方式,让用户能够随时随地与朋友保持联系。本地生…

人工智能AI聊天chatgpt系统openai对话创作文言一心源码APP小程序功能介绍

你提到的是一个集成了多种智能AI创作能力的系统,它结合了OpenAI的ChatGPT、百度的文言一心(ERNIE Bot)以及可能的微信WeLM(或其他类似接口)等。这样的系统确实能够极大地提高创作效率,并且在各种场景下为用…

SpringBoot接收参数的19种方式

https://juejin.cn/post/7343243744479625267?share_token6D3AD82C-0404-47A7-949C-CA71F9BC9583

秋招算法——AcWing101——拦截导弹

文章目录 题目描述思路分析实现源码分析总结 题目描述 思路分析 目前是有一个笨办法,就是创建链表记录每一个最长下降子序列所对应的节点的链接,然后逐个记录所有结点的访问情况,直接所有节点都被访问过。这个方法不是很好,因为需…

【Qt】Qt组件设置背景图片

1. 方法1(paintEvent方式) 使用paintEvent()实现 1. .h文件中添加虚函数 protected:void paintEvent(QPaintEvent *event) override;添加虚函数方法: 选中父类,点击鼠标右键点击重构点击 Insert Virtual Funtion of Base Class…

小朋友台灯什么品牌好,分享最好的台灯品牌排行榜

小朋友台灯什么品牌好?台灯作为我们日常生活中重要的桌面照明工具,对于办公族的工作和学生的学习都扮演着关键角色。长期使用质量不佳的台灯可能会对我们的视力健康造成不利影响,尤其是对于眼睛尚在发育阶段的青少年来说,这种影响…

5G技术相关部分图解

1、面向5G商用网络的全系列解决方案 面向5G商用网络的全系列解决方案涵盖了从核心网到接入网的各个方面,确保网络的高性能、高可靠性和高安全性 2、2\3\4\5G带宽图解 G带宽的提升将推动许多新型应用的发展,并提供更快速、更可靠的移动通信体验。然而…

一个panic问题引起对percpu变量的思考

1 问题引入 最近在分析一个panic问题时&#xff0c;发现panic现场无法与log对应起来。 先贴log: <1>[ 180.089084] Unable to handle kernel NULL pointer dereference at virtual address 00000001 <1>[ 180.099551] pgd 8bbde651 <1>[ 180.107775] …

AXI UART 16550 IP核简介

AXI UART 16550 IP核实现了PC16550D UART的硬件和软件功能&#xff0c;该UART可以在16450和16550 UART模式下工作。 一、 功能 AXI UART 16550 IP核执行从AXI主设备接收的字符的并行到串行转换&#xff0c;以及从调制解调器或串行外设接收的字符的串行到并行转换。它支持发送…

GPT3.5、GPT4、GPT4o的性能对比

理论总结 随着版本的升级,模型在参数数量、语言理解能力、生成文本质量、多模态能力、推理能力等方面均有显著提升。GPT-4.0作为最新改进版,提供了最先进的功能和性能。 实际对比 1.1.GPT3.5 1.2.GPT4 1.3.GPT4o 在语义理解上,无差别。 下面测试下代码能力。 测试问题 我…

uni-app:音频播放 uni.createInnerAudioContext()

uni.createInnerAudioContext() 创建并返回内部 audio 上下文 innerAudioContext 对象 简单实现音频播放&#xff1a; let innerAudioContext uni.createInnerAudioContext(); innerAudioContext.src ../../../../static/ok.MP3;//音频地址 innerAudioContext.play(); inn…

Pikachu 靶场 SQL 注入通关解析

前言 Pikachu靶场是一种常见的网络安全训练平台&#xff0c;用于模拟真实世界中的网络攻击和防御场景。它提供了一系列的实验室环境&#xff0c;供安全专业人士、学生和爱好者练习和测试他们的技能。 Pikachu靶场的目的是帮助用户了解和掌握网络攻击的原理和技术&#xff0c;…

【案例】使用Vue实现拖拽课表

效果展示 效果说明 点击左侧的课程并进行拖拽&#xff0c;拖拽到要开设本课程的地方然后松手&#xff0c;即可将本节课设置为当前所拖拽的科目并且背景色为当前科目的背景色&#xff0c;当多次拖拽到同一节课的时候将会实现后者覆盖前者的效果。 效果实现代码 第一步&#x…

波场TRON超级代表候选名单“迎新” 携手谷歌云打造更可靠基础设施

来自波场TRON DAO的信息显示,谷歌云已加入波场TRON区块链上的超级代表候选名单。分析人士认为,这将为波场TRON网络提供更加稳定和可靠的区块生成和交易打包服务,有助于进一步加强波场TRON网络的安全性和稳定性,推动区块链技术的发展和创新。此举也将提高波场TRON在加密货币领域…

一图流解释Java中线程状态的转换

目录 一.Java中的几大线程状态 二.线程之间的相互转换 ▐ NEW --> RUNNABLE ▐ RUNNABLE <--> WAITING ▐ RUNNABLE <--> Timed Waiting ▐ RUNNABLE<--> BLOCKED ▐ RUNNABLE<-->TERMINATED 一.Java中的几大线程状态 简单来说线程可以处于…

VC++6.0 Sqlite3调用例子

1,为什么要使用Sqlite3? SQLite 是一个软件库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。 2,为什么使用SQLite version 3.8.4.3 2014-04-03 16:53:12的版本…

新书速览|Django 5 Web应用开发实战

构建未来&#xff0c;用Django 5打造全新Web应用 本书内容 《Django 5 Web应用开发实战》集Django架站基础、项目实践、开发经验于一体&#xff0c;是一本从零基础到精通Django Web企业级开发技术的实战指南。《Django 5 Web应用开发实战》内容以Python 3.x和Django 5版本为基础…