什么是 Webhook?
Webhook 是一种事件驱动的轻量级通信,可通过 HTTP 在应用之间自动发送数据。Webhook 由特定事件触发,可自动实现 应用编程接口(API)之间的通信,并可用于激活工作流,例如在 GitOps 环境中。
Webhook 可以将事件源连接到自动化解决方案,因此,它可以用来启动事件驱动型自动化以便在发生特定事件时执行各种 IT 操作。
怎么理解 Webhook?
你可以将它🤔下述场景:
电话短信通知: 你的银行在你消费时,会自动给你发送一条短信通知。你不需要不断地打电话给银行询问是否有新的消费记录,银行会在事件发生时(你消费了)主动通知你。Webhook 就像这个短信通知,当某个事件在源应用中发生时,它会主动发送一个"消息"到你指定的"地址"。
你告诉朋友到家了就发消息: 你和朋友一起回家,你先到家了,你告诉朋友"你到家了就给我发个消息"。朋友到家后,就会主动给你发消息。这个"发消息"的行为就是 Webhook。

Webhook 的核心机制
- 事件触发 (Event Trigger): Webhook 的核心是"事件"。只有当预设的事件发生时,Webhook 才会工作。例如,在一个电商平台,事件可以是"新订单创建"、"订单状态更新"等。
- HTTP 请求 (HTTP Request): 当事件被触发时,源应用程序会向一个预先配置好的 URL 地址(通常称为 Webhook URL 或 Callback URL )发送一个 HTTP POST 请求。此 URL 指向一个专门设计用于接收和处理这些 webhook 通知的 Web 服务器。
- 数据负载 (Payload): 这个 HTTP 请求通常会包含一个数据负载 (payload) ,里面是关于被触发事件的详细信息,通常以 JSON 或 XML 格式呈现。例如,新订单创建的 Webhook 会发送新订单的ID、金额、商品列表等信息。
- 实时性 (Real-time): Webhook 的主要优势在于它的实时性。一旦事件发生,信息几乎是即时地发送出去,这与传统的 API 轮询 (Polling) 方式形成了鲜明对比(轮询是客户端定期去询问服务器是否有新数据,效率较低)。
Webhook 与 API 的区别
API (Application Programming Interface): 像是一个 "菜单" ,你通过它向服务器 "点菜" ,服务器根据你的请求提供服务。你需要主动发起请求才能获取数据或执行操作。
Webhook: 像是一个 "通知服务" ,你告诉服务器当某个 "事件" 发生时, "主动" 把信息发送给你。你不需要主动去请求,而是被动接收信息
Webhook vs. 消息中间件:核心区别

Webhook与传统前后端交互的区别
Webhook 的核心是"后端到后端"或"服务到服务"的通信,而不是前端直接向后端发送 Webhook 请求。
Webhook 的关键在于"事件发生时的主动通知" 。前端通常是被动地接收数据 或触发用户操作。如果前端直接发送 Webhook 请求,那么:
- 安全性问题: 前端代码是公开的,如果 Webhook URL 被硬编码在前端,容易被滥用或攻击。
- "推"的本质: Webhook 是"推"的机制,意味着当源头(通常是后端)发生某个事件时,它才主动发送数据。前端通常是在用户交互后,主动"拉取"数据或触发操作。
- 复杂性: 如果前端负责监控事件并发送 Webhook,这会大大增加前端的复杂性,并且很多后端服务之间的集成场景,前端根本无法参与。
前端页面请求一次后端接口,后端接口在执行自己逻辑之后,后端会自己调用另一个后端接口进行操作?
常规的后端服务间调用

Webhook 的真实场景

两者关键的区别在于:
-
"事件发生"和"谁主动":
- 在常规调用中,是你的后端服务 A 主动去请求第三方服务 B。
- 在 Webhook 中,是第三方服务 B(支付网关)在特定事件(支付成功)发生后,主动向你的后端服务 A 发送通知。 你的后端服务 A 只需要提供一个接口来监听和接收这个通知。
-
异步通知:
- Webhook 是一种异步通知机制。你的后端服务 A 不必等待支付网关的同步响应来知道支付结果。当支付完成(无论是立即还是稍后),支付网关会主动"推送"结果给你。这对于耗时较长或不确定的第三方操作非常有用。
-
URL 的角色:
- 在常规调用中,你的后端服务 A 调用的是支付网关的 API 端点。
- 在 Webhook 中,支付网关调用的是你的后端服务 A 提供的"Webhook URL" 。这个 URL 是你预先配置在支付网关那里的,告诉它"有事请通知我这个地址"。
实现webhook是不是可以使用消息中间件?
Webhook 和消息中间件(如 Kafka、RabbitMQ 等)虽然都涉及消息传递,但它们解决的问题、通信模式和设计目标根本不同。
实现 Webhook 不是使用消息中间件。
Webhook 和消息中间件(如 Kafka、RabbitMQ 等)虽然都涉及消息传递,但它们解决的问题、通信模式和设计目标根本不同。
Webhook 的核心:点对点、推式通知
Webhook 的本质是一个点对点 的、由事件源主动发起的 HTTP 推送通知。
当你设置一个 Webhook 时,你是在告诉服务 A(事件源,例如 GitHub):"当事件 X 发生时,请直接向我的服务 B 的 URL 发送一个 HTTP 请求。" 服务 A 会立即构建并发送这个请求,然后等待服务 B 的响应(比如 200 OK
)。
关键在于:
- 直接性: 事件源直接与接收方通信。
- 同步性(对发送方而言): 发送方发送请求后,通常会等待接收方的响应。
- 耦合性: 发送方需要知道接收方的具体 URL。
- 简易性: 实现起来相对简单,通常只需一个 HTTP POST 请求。
消息中间件的核心:解耦、异步、可靠的消息队列
消息中间件提供了一个中心化 的、解耦 的通信平台。它实现了生产者-消费者模式。
当你使用消息中间件时,服务 A(生产者)将消息发送到中间件 的一个队列或主题中。服务 B(消费者)则从这个队列或主题中拉取 或订阅消息。
关键在于:
- 解耦: 生产者和消费者之间没有直接联系,它们都只与中间件交互。
- 异步性: 生产者发送消息后无需等待消费者处理,可以立即进行其他操作。
- 可靠性: 中间件通常提供消息持久化、重试、事务、死信队列等机制,确保消息不会丢失。
- 扩展性: 一个生产者可以向多个消费者广播消息,或多个消费者可以共同消费一个队列,实现负载均衡。
- 复杂性: 需要部署、配置和管理中间件服务。
为什么不能用消息中间件直接实现 Webhook?
-
通信模式不符:
- Webhook: 事件源 主动推送到 一个外部的 HTTP URL。这意味着事件源需要知道接收方的公网地址,并能直接访问它。
- 消息中间件: 生产者 推送到 中间件,消费者 从中间件拉取。外部服务无法直接将消息推送到你的内部消息队列,因为你的消息队列通常在内网,不直接暴露给公网。
-
安全和网络隔离:
- 为了安全,你的消息中间件通常部署在私有网络中,不直接暴露给互联网。你不会希望 GitHub 这样的外部服务能直接连接到你的 Kafka 或 RabbitMQ 集群。
- Webhook 接收方暴露的是一个 HTTP/HTTPS 端点,这是标准的 Web 通信方式,可以通过防火墙、API 网关等进行保护。
-
职责分离:
- Webhook 解决的是"外部服务通知我内部系统"的问题。
- 消息中间件解决的是"内部系统之间高可靠、异步地传递消息"的问题。
典型的 Webhook 接收方实现如何结合消息中间件?
流程示例:
-
GitHub(Webhook 发送方)
- 事件:代码
push
。 - 动作:向你的服务器的 Webhook URL 发送 HTTP POST 请求。
- 事件:代码
-
你的服务器(Webhook 接收方)
- Web 服务器层: 提供一个公开的 HTTP POST 端点 (
/webhooks/github
)。 - 安全验证层: 接收到请求后,立即验证签名,确保请求来自 GitHub。
- 消息转发层: 这里,你可以将接收到的 GitHub Webhook Payload 封装成一条消息,然后将其发送到你内部的 消息中间件(例如 Kafka 或 RabbitMQ)的某个队列中。
- 即时响应: 你的 Webhook 端点立即向 GitHub 返回
200 OK
响应。
- Web 服务器层: 提供一个公开的 HTTP POST 端点 (
-
你的后台消费者服务(通过消息中间件)
-
这是一个独立的后台服务,它订阅或监听你消息中间件中的那个队列。
-
当它从队列中获取到 GitHub Webhook 消息时,才开始执行耗时的业务逻辑,例如:
-
触发 Jenkins 构建。
-
更新数据库。
-
发送 Slack 通知。
-
-