新我们如何抓出挂错模型的卖家,并在发生时为你退款。
UberLLM

Webhook 对比 API:推送、轮询以及何时使用它们

Webhook 与 API 在方向、流量、可靠性和成本方面进行比较,并说明何时使用它们以及如何将它们结合用于异步 AI 媒体任务。

关于 webhook 与 API 的流行建议是不完整的:将 webhook 用于实时更新,将 API 用于其他所有情况。这忽略了最难的部分。webhook 接收器是一个异步消息消费者,选择推送交付意味着要承担处理重复消息、遗漏通知、身份验证和恢复的责任。真正有用的比较不是推送与拉取。而是流量经济学与运营控制,并为任何失败的通道提供恢复路径。

目录

Webhook vs API 一览

标准 API(请求-响应或轮询) Webhook(推送通知)
方向 客户端发送请求,服务器响应 提供方发送 HTTP 请求到客户端 URL
谁发起 客户端 提供方,当事件发生时
时机 当客户端请求时 当事件发生时
最适合 当前状态、历史记录、数据回填、数据对账 在状态改变或任务完成时通知应用
客户端需求 仅需出站 HTTP 访问 公共 HTTPS 端点、签名验证、存储
交付 如果传输成功,直接响应每个请求 通常是至少一次交付,带有有限重试、可能重复和乱序
故障恢复 客户端重试并再次检查 提供方重试;消费者通过 API 进行去重和对账
成本模式 流量随轮询频率增长 流量随事件量增长

Webhook 是一种基于 HTTP API 构建的事件交付机制,而非其替代品。 大多数生产集成都需要两者:一个用于命令和权威读取的请求路径,以及一个用于变更通知的路径。

假设您的应用程序提交了一个视频生成任务。使用 API,您的后端会使用保存的任务标识符发送一个 GET 请求,并接收该任务的当前状态。您的应用程序可以选择何时请求、等待多久以及请求失败时如何处理。

使用 Webhook,提供方会将一个任务完成事件发送到您注册的端点。您的后端接受该通知并安排下一步操作,例如检索完成的资产。原始浏览器会话无需保持连接。

将命令与通知分离

提交工作和得知其完成是不同的操作。API 可以立即接受任务,而无需保持连接开放直到底层计算完成。Webhook 随后提供一个单独的完成信号。

这种区别避免了一个常见的设计错误:将每个异步操作都视为必须保持开放的 HTTP 请求。它也避免了相反的错误,即试图将事件通知用作当前状态的完整记录。

首要决定: 您的应用程序需要在某些事物发生变化时做出反应,还是仅在有人询问时才需要答案?

如果用户打开任务历史记录屏幕,则获取当前记录。如果一个已完成的任务应该在没有人查看该屏幕时触发资产交付,则使用事件驱动路径。两种模式都不能消除处理网络故障的需要,但每种模式都使调用者处于不同的恢复位置。

每种模式如何移动数据

对于 轮询,客户端会根据计时器重复发送状态请求,无论是否有任何更改。对于 webhook,提供方会在事件发生后发起请求,因此通知流量是根据活动而非时间来变化的。

Nylas webhook 与轮询指南提供了底层流量示例:每 60 秒 轮询一个资源意味着每天 1,440 次请求,而其对 10,000 个账户 的比较产生了每天 2.88 万次轮询请求,而 webhook 交付量约为 500,000 次。

按轮询间隔和事件速率划分的流量和延迟

场景 每天的请求或交付量 检测延迟
每 60 秒轮询一个资源 1,440 次请求 平均 30 秒
每 5 分钟轮询一个资源 288 次请求(根据间隔计算) 平均 2.5 分钟
10,000 个账户每 5 分钟轮询一次 2.88 万次请求 平均 2.5 分钟
10,000 个账户各接收约 50 条事件通知 约 500,000 次交付 事件分派时间加上任何重试延迟
文本响应逐 token 流式传输 每次生成一次请求 token 在生成时到达

轮询平均值假设更改独立于轮询计划发生。它们描述的是等待下一次检查的时间,而不是提供方执行工作所花费的时间。

较短的间隔通过发送更多请求来缩短发现时间。较长的间隔会减少流量,但会使已完成的工作长时间未被发现。在账户规模下,即使是适度的计划也会产生大量流量,因为每个不活跃的账户仍然会被检查。

Webhook 交付消除了固定的检查计划,但交付计数并非完整的底层架构开销。通知后的 API 查找、交付重试、接收方存储和 worker 执行仍然会消耗资源。

这些是不同的通信模式,而非可互换的标签。

一张信息图,比较了三种数据传输模式:轮询、Webhook 和 Streaming API,用于客户端-服务器通信。

Streaming 解决了不同的问题

Streaming 文本响应会保持请求开放,并在 token 生成时返回它们。对于交互式编码助手而言,首个 token 的时间 和输出的连续性比接收单独的完成回调更重要。

我们的文本响应逐 token 流式传输,而图像和视频任务则会返回一个任务,您可以在任务准备就绪时轮询或接收 webhook 通知。 媒体 API 文档是实现该面向任务的请求路径的起点。

在选择轮询间隔之前,请估算每个资源的事件速率。一个不活跃的资源和一个持续变化的资源不应自动共享相同的计划。

对于轮询,较短的间隔会以更多流量换取更少的检测延迟。Webhook 避免了这种特定的交换,但取而代之的是运行可靠接收方的成本。

您必须在设计中考虑的可靠性权衡

Webhook 交付通常是至少一次,而非恰好一次。这描述的是交付模型,而非提供商会永远重试的承诺。有限的重试仍然可能导致事件未交付,因此,请为最坏情况设计接收器,而非理想情况。

超时并不能告诉发送方下游发生了什么。您的接收器可能会将事件提交到存储,然后却在网络中丢失确认。当发送方重试时,您的应用程序会再次收到相同的事件,并且必须优雅地处理它。

为每种故障匹配保护措施

  • 重复交付: 在唯一约束下存储稳定的事件标识符。在提供商区分事件和交付尝试的情况下,通过事件标识而非尝试标识来去重业务处理。
  • 重复的副作用: 使资产发布、账户更新和客户通知具有幂等性。入口去重对于在执行操作后但在记录成功之前崩溃的工作器来说毫无作用。
  • 乱序事件: 在应用转换之前,检查权威状态或已记录的资源版本。延迟的“处理中”事件绝不能覆盖已完成的任务。
  • 处理缓慢: 在将耗时的工作交给队列工作器之前,验证、持久接受并确认事件。

提供商的重试策略并非互通。Supabase webhook 文档要求在 20 秒内返回 2xx 响应,使用指数退避,并在 五次失败尝试 后停止。Svix 交付保证指南记录了 Dynamic 的首次尝试加上 大约一天内的五次重试,以及 Glean 针对特定状态的重试规则。

按提供商分类的已记录 webhook 重试行为

提供商 何为成功 重试行为
Supabase 20 秒内返回 2xx 响应 指数退避,五次失败尝试后停止
Dynamic 2xx 响应 首次尝试加上大约一天内的五次重试
Glean 2xx 响应 重试连接失败、超时、408, 429 和 5xx;其他非-2xx 响应为终止性响应

确认是持久性边界

在持久存储之前返回成功会创建一个丢失窗口:发送方停止重试,但您的应用程序没有任何可恢复的内容。仅在媒体处理后返回成功会产生相反的问题:不必要的超时和重复交付。确认持久接受,而非已完成的业务工作。

签名验证应在信任 payload 之前进行。当签名方案要求时,保留原始请求正文,并遵循提供商记录的验证程序,而非对重新序列化的对象进行签名。

为耗尽重试次数的工作器添加死信处理,以及连接事件 ID、任务 ID、确认失败和处理结果的交付可观测性。对于同一工作流的轮询部分,使用返回的状态码对故障进行分类:UberLLM 的 API 会拒绝带有 402, 404, 429 和 503 等错误代码的调用,这使得对账作业能够将计费拒绝与限流或暂时不可用的卖家区分开来。

错过的轮询可以通过再次检查来恢复。错过的 webhook 需要另一次交付,或者一个独立的对账过程,该过程会按计划重新读取权威任务状态。无论您是否暴露接收器,都应构建该过程;它是将至少一次交付转化为有效恰好一次处理的关键。

当轮询是更安全的选择时

Webhooks 是一个交付可靠性问题,而不仅仅是更快的 API。 如果您的应用程序无法支持接收方契约,轮询可能是更可靠的选择。

操作上的差异在消费者边界处最容易看出。

一张比较图,说明了为什么轮询是 API 集成中比 webhook 交付更可靠的替代方案。

桌面代理、防火墙后的内部工具或临时的 CI 运行器可能具有出站访问权限,但没有稳定的入站地址。让这些客户端接收回调可能需要额外的托管服务、组件之间的身份验证以及将持久性移交回原始调用者。那是基础设施,而不是一个小的配置更改。

识别有利于轮询的约束条件

  • 没有稳定的公共 endpoint: 保持通信出站,而不是暴露临时开发环境。
  • 没有持久的事件消费者: 在构建安全的存储和处理时轮询权威状态。一个忘记已接受事件的接收方并不是一种改进。
  • 消费者控制的恢复: 根据您自己的并发限制、维护窗口和应用程序截止日期安排检查。

假设开发人员笔记本电脑上的构建工具提交了一个远程媒体任务。它可以定期检查直到完成,在开发人员取消时停止,并从保存的任务标识符恢复。对于少量活跃作业,这可能比维护一个始终可用的接收方更简单、更便宜。

轮询仍然需要纪律。在瞬时故障时退避,避免同步每个客户端的检查,并停止检查终端任务。出站请求也可能导致重试风暴。

随附的视频提供了另一种可视化请求和回调之间区别的方式。

选择您的消费者可以可靠恢复的模式,而不是具有最快成功演示的模式。

入站 webhook 流量增加了 endpoint 安全性、签名检查、排队、重复抑制以及可用性要求。轮询让您拥有明确的控制权,控制下一次操作何时发生,尽管提供商的速率限制仍然适用。

当入站交付可行且频繁事件证明其合理性时,使用带有轮询回退的 webhook;否则,请使用您自己的节奏、并发和超时进行轮询。

如何构建媒体作业的混合流程

混合集成将回调视为检查工作的提示,而不是工作存在的唯一证据。持久化的任务身份连接了初始请求、传入通知、恢复检查和最终客户结果。

我们使用异步任务跟踪和 webhook 回调来保持大容量媒体工作流程的顺畅运行。对于图像和视频作业,这种跟踪意味着即使一个卖家中断,也不会丢失客户的作业。

该工作流程将提交、通知和状态恢复分开处理。

一个图表,概述了使用 API 和 webhook 处理媒体作业的三步混合工作流程。

建立任务的持久所有权

  1. 通过 API 提交并保存返回的 task ID。 在开始下游工作之前,将其以排队状态持久化。如果可能,请事先创建本地提交记录,因为快速回调可能会抢在提交响应之前到达。常见的错误是假设回调总是在数据库提交之后才到达。保留未匹配的事件以供后续关联。

  2. 注册一个接收器,持久地将接受的事件入队。 保持请求处理程序精简,并在安全接受后立即确认。不要在存储之前返回成功,也不要在处理程序内部下载或转换完成的资产。

  3. 验证真实性,然后去重处理。 签名验证必须在事件被信任或确认之前在入口处进行;然后工作程序在应用效果之前检查持久化的事件身份。常见的错误是将其视为处理后的可选清理。保持接受和处理状态分离,以便中断的工作程序可以安全地恢复。

收敛到权威性完成

  1. 获取任务的权威状态。 在将客户作业标记为完成之前,使用保存的 task ID。事件可能只包含一个标识符,延迟的通知可能描述的是较旧的转换。对于图像编辑的实现,图片编辑 API 指南提供了一个具体的请求工作流程供您构建。

  2. 轮询超出预期时间窗口仍处于待处理状态的任务。 对每个检查周期使用退避、抖动和最大尝试次数。当回调缺失时,不要盲目地重新提交生成,因为原始任务可能已经完成。

  3. 设置应用程序截止日期并每日协调过期任务。 区分生成失败和状态检查失败。如果提供者状态在您的截止日期仍未知,请记录明确的恢复或失败结果,而不是让客户界面无限期地排队。

健康检查: 每个保存的 task ID 都必须在您的超时时间内导致一个最终的应用程序结果,无论是完成还是失败。保持未解决的提供者状态对操作员可见,这样应用程序超时就不会放弃仍需要恢复的结果。

按工作负载和约束选择

从工作负载开始,然后排除部署无法支持的任何模式。如果接收客户端无法接受入站请求,或者团队无法从中断的处理中恢复,那么最快的通知机制也无济于事。

工作负载到模式的映射

工作负载 推荐模式 主要原因
短文本生成或编码响应 带 streaming 的同步 API 需要快速获得一个响应
图像、视频、音乐或语音任务 通过 API 提交,完成后 webhook 通知,轮询作为备用 完成时间不可预测
没有公共 endpoint 的移动或浏览器客户端 轮询 无法接受提供方发起的入站调用
历史记录回填或对账 API 列表调用 需要当前和历史状态
高流量事件流,例如订单状态 带幂等消费者和对账的 webhook 当事件速率远低于建议的轮询速率时适用

浏览器仍然可以通过其自己的后端接收应用程序更新,但该后端拥有 webhook 接收器。不要将提供方凭据或回调验证密钥放入浏览器中以规避此责任。

工作负载和部署约束应一并评估。

一张图表,说明了根据工作负载和约束在同步 API 调用和排队媒体任务之间进行选择。

使用总运营成本作为决胜因素

在 Xictron 的 webhook 架构文章 中引用的一项分析发现,30 百万次轮询请求中只有 1.5% 次返回了更新。这说明了调优不当的轮询如何浪费流量,而不是说每个 webhook 集成都会成本更低。

将轮询间隔、事件频率、有效载荷大小和提供方限制与接收器托管、队列存储、监控和事件响应进行比较。还要计算您的 webhook worker 仍然需要的 API 读取次数。轻量级通知后进行权威性获取并非无请求架构。

对于多提供方应用程序,请检查事件模式一致性和回退行为。将任务状态规范化到您自己的应用程序模型中,可能比通知速度上的微小差异更重要。

选择规则: 优先选择满足用户需求的最简单主路径,然后在优化延迟之前投入资源建设恢复路径。

当应用程序需要对请求的响应时,使用 API。当应用程序必须对变化做出反应并能操作安全、持久的接收器时,使用 webhook。为长时间运行的任务添加独立的状态检查,并在无法进行入站交付时保持轮询由消费者控制。

在实施之前,写下您每个资源的预期事件速率、是否可以暴露稳定的 endpoint 以及如何处理重复处理。然后发出一个普通的 API 请求,并在添加回调之前验证您可以保存和检索生成的任务。


UberLLM 通过一个 API key 提供所有模型,并接受 OpenAI 和 Anthropic 的线格式,因此现有客户端可以使用适当的 base URL 和凭据。对于图像和视频工作流,当结果准备就绪时,选择任务轮询或 webhook 通知。访问 UberLLM 以测试请求路径,然后添加您的应用程序所需的完成和恢复路径。