Svix - Webhooks as a service
网站 | 文档 | 社区 Slack
Svix 是企业级就绪的 webhook 服务
Svix 让开发者轻松发送 webhooks。开发者只需发起一次 API 调用,Svix 便会处理投递、重试、安全等事宜。更多信息,请参阅 Svix 主页。
文档
你可以在 https://docs.svix.com 找到通用使用文档。要查看包含所有官方客户端库中每个端点代码示例的完整 API 文档,请访问位于 https://api.svix.com 的 API 文档站点。
支持 & 社区
- GitHub Issues - 报告问题并提出建议。
- Community Forum - 提问并发起讨论!
- Slack - 来和我们聊天吧!
为了及时了解新功能和改进,请务必关注我们的仓库!

客户端库概览
| ⚡️ 功能细分 ⚡️ | |||||||
|---|---|---|---|---|---|---|---|
| 语言 | 官方支持 | API 支持 | Webhook 验证 | 其他备注 | |||
| Go | ✅ | ✅ | ✅ | ||||
| Python | ✅ | ✅ | ✅ | ||||
| Typescript/Javascript | ✅ | ✅ | ✅ | ||||
| Java | ✅ | ✅ | ✅ | 计划支持异步。(如果您使用 kotlin,请查看我们的 kotlin 库以获取协程支持。) | |||
| Kotlin | ✅ | ✅ | ✅ | ||||
| Ruby | ✅ | ✅ | ✅ | ||||
| C# (dotnet) | ✅ | ✅ | ✅ | ||||
| Rust | ✅ | ✅ | ✅ | ||||
| PHP | ✅ | ✅ | ✅ | ||||
| Terraform | ✅ | ✅ | N/A | ||||
试用 CLI
Svix CLI 已发布在 npm 上,包名为 svix-cli。你可以直接使用 npx 运行它,无需安装任何内容:
npx svix-cli --help
或将其全局安装:
npm install -g svix-cli
svix-cli --help
运行服务器
有多种方式可以启动 Svix 服务器。Docker 可能是最常见的方式,但你可以选择最适合你的方式。
Svix 服务器使用 Rust 🦀 编写,这意味着你可以将其编译为适用于多种目标的静态库。有关更多信息,请参阅下面的从源代码构建部分。
有关可用设置的更多信息,请参阅下面的服务器配置部分。
部署
Docker
你可以使用来自 Docker Hub 的官方 Svix Docker 镜像。你可以使用 latest 标签,或者改用 版本化标签 之一。
你可以使用带有 docker compose(最简单)、docker swarm(高级)的示例 docker-compose.yml 文件,或者单独运行容器。
使用 Docker Compose
这种替代方案最简单,因为它还会启动并配置 redis 和 postgresql。
这假设你已安装 Docker Compose v2。
cd server
docker compose up
独立容器
运行独立容器稍微复杂一些,因为它要求你设置一些环境变量,并使它们指向你的 redis 和 postgres 实例。
你可以使用 -e 标志将单个环境变量传递给 docker,或者创建一个类似 development.env 的文件,并像下面的示例那样使用 --env-file 标志:
docker run \
--name svix-server \
-p 8071:8071 \
--env-file development.env \
svix/svix-server
从源码构建
Svix 服务器使用 Rust 🦀 编写,需要一个 Rust 构建环境。
如果你已经拥有该环境,只需运行 cargo build,否则,请参阅 Svix 服务器 README 以获取有关从源码构建服务器的更多信息。
运行时依赖
服务器需要以下运行时依赖项才能正常工作:
- 一个 PostgreSQL 服务器 - 用于存储事件。
- 一个可选的 Redis 服务器,版本 6.2.0 或更高 - 用于任务队列和缓存。
Redis/Valkey 注意事项
持久性
请注意,建议在 Redis 中启用持久性,以便在 Redis 服务器重启和升级期间持久化任务。
驱逐策略
请确保你的 Redis 实例配置为在未显式设置 expire 策略的情况下不驱逐键。这意味着应将 maxmemory-policy 设置为 noeviction 或任何可用的 volatile- 策略。有关更多信息,请参阅 Redis/Valkey 文档。
服务器配置
配置 svix-server 有三种方式:环境变量、.env 文件以及配置文件。
配置文件
你可以在 svix-server 的当前工作目录中放置一个名为 config.toml 的文件,它将自动加载该文件。
你可以查看示例文件以获取更多信息和支持设置的完整列表:config.toml。
以下是最重要配置的快速示例:
# The JWT secret for authentication - should be secret and securely generated
jwt_secret = "8KjzRXrKkd9YFcNyqLSIY8JwiaCeRc6WK4UkMnSW"
# The DSN for the database. Only postgres is currently supported.
db_dsn = "postgresql://postgres:postgres@pgbouncer/postgres"
# The DSN for redis (can be left empty if not using redis)
redis_dsn = "redis://redis:6379"
# What kind of message queue to use.
queue_type = "redis"
环境变量(变量或 .env)
或者,你可以通过为每个受支持的设置设置等效的环境变量来配置 svix-server。环境变量可以直接传递,也可以通过在 .env 文件中设置它们。
环境变量的名称与配置名称相同,但它们全部为大写,并以 SVIX_ 作为前缀。
例如,如果上述示例配置通过环境变量传递,其形式如下:
# The JWT secret for authentication - should be secret and securely generated
SVIX_JWT_SECRET = "8KjzRXrKkd9YFcNyqLSIY8JwiaCeRc6WK4UkMnSW"
# The DSN for the database. Only postgres is currently supported.
SVIX_DB_DSN = "postgresql://postgres:postgres@pgbouncer/postgres"
# The DSN for redis (can be left empty if not using redis)
SVIX_REDIS_DSN = "redis://redis:6379"
# What kind of message queue to use.
SVIX_QUEUE_TYPE = "redis"
OpenTelemetry
您可以将跟踪信息发送到 OpenTelemetry Collector,它允许将跟踪事件转发到多个外部应用程序/服务,例如 DataDog、Jaeger、NewRelic、Prometheus、Sentry、Signoz 和 Zipkin。
您可以在这些说明中查看更多内容。
Connection Pool Size
db_pool_max_size 配置参数控制 PostgreSQL 连接池的最大允许大小。此值默认为最大 100,但增加此值可能会显著提高应用程序性能。在调整这些参数时,您可能还需要考虑 Postgres 和 PGBouncer 的配置参数。
redis_pool_max_size 参数控制每个 Svix 实例的 Redis 连接池的最大大小。其默认值为 100。请注意,只有 redis queuing 利用了连接池——缓存是完全异步的,因此不会从连接池中受益。因此,您可能不需要调整此参数。
SSRF Attacks and Internal IP Addresses
为防止 SSRF 攻击,默认情况下会阻止向内部 IP 地址的消息分发。然而,我们理解这并不满足所有用户的需求,例如,服务只能在内部访问。要绕过这些限制,请参阅 whitelist_subnets 配置选项,该选项接受一个 CIDR 表示法的子网数组,以允许向这些子网分发消息。
Webhook signature scheme (symmetric vs asymmetric)
为确保消息的安全性和完整性,Svix 在发送前会对所有 webhook 消息进行签名。 Svix 支持两种签名方案:对称(预共享密钥)和非对称(公钥)。
对称签名速度显著更快(签名约快 50 倍,验证约快 160 倍),且更为简单(这使得您的客户更容易进行验证),但它们需要每个端点使用一个预共享密钥(端点密钥)才能工作。另一方面,非对称签名只需要与您的客户共享一个公钥(而非密钥)。
基于上述原因,推荐使用对称密钥,这也是 Svix 的默认设置。其使用方法记录在文档中的验证签名部分]。
然而,在某些场景下,使用非对称签名可能更有益,因此它们也得到支持。更多信息请参阅下方的非对称签名部分]。
身份验证
使用用正确密钥生成的有效 JWT 作为 Bearer。
E.g:
Authorization: Bearer <JWT_TOKEN_HERE>
或者使用
svix-server jwt generate
或者,如果您自行生成,请确保将 org_23rb8YdGqMT0qIzpgGwdXfHirMu 用作 sub 字段,并将 H256 用作算法。
使用密钥 x 的有效 JWT 示例(以便您可以查看其结构):
// JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTUxNDA2MzksImV4cCI6MTk3MDUwMDYzOSwibmJmIjoxNjU1MTQwNjM5LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.USMuIPrqsZTSj3kyWupCzJO9eyQioBzh5alGlvRbrbA
// Structure (when decoded):
{
"iat": 1655140639,
"exp": 1970500639,
"nbf": 1655140639,
"iss": "svix-server",
"sub": "org_23rb8YdGqMT0qIzpgGwdXfHirMu"
}
使用不同的签名算法
如上所述,签名 JWT 的默认算法是 HS256。您可以通过将 jwt_algorithm 配置设置为以下受支持的值之一来选择不同的算法:HS384、HS512、RS256、RS384、RS512 或 EdDSA。
运营(入站)webhooks
运营 webhooks 是您可以订阅以接收 svix-server 上发生的重要事件通知的 webhooks。支持的事件列表可在 API 参考的 webhooks 部分 中找到。
运营 webhooks 使用 Svix,并由一个具有以下 ID 的特殊账户服务账户控制:org_00000000000SvixManagement00。
第一步是通过将 operational_webhook_address 配置设置为指向您的 Svix 服务器来启用它。此设置最常见的值是 http://127.0.0.1:8071,但根据您特定的设置,它可能有所不同。
上述步骤在此实例上启用了运营 webhooks,下一步是为您的特定组织启用它。如上所述,运营 webhooks 在幕后使用普通的 Svix 账户,因此我们首先需要获取此账户的认证令牌。为此,您应该运行:
svix-server jwt generate org_00000000000SvixManagement00
这将为您提供一个特殊的 JWT,用于访问操作 Webhooks 账户,该 JWT 与您在与 Svix 交互时使用的常规 JWT 不同。例如,假设它返回的 JWT 为 op_webhook_token_123。
要为特定账户启用操作 Webhooks,我们需要首先在服务账户中为其创建一个应用程序(请记住:操作 Webhooks 只是在后台使用 Svix)。我们将使用默认的 Svix 账户作为示例:org_23rb8YdGqMT0qIzpgGwdXfHirMu。
curl -X 'POST' \
'http://localhost:8071/api/v1/app/' \
-H 'Authorization: Bearer op_webhook_token_123' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"name": "Operational webhook for default org",
"uid": "org_23rb8YdGqMT0qIzpgGwdXfHirMu"
}'
就是这样,我们现在已为默认账户启用了操作 Webhooks。剩下的唯一任务是添加一个端点,用于接收操作 Webhooks 的发送。例如:
curl -X 'POST' \
'https://api.eu.svix.com/api/v1/app/org_23rb8YdGqMT0qIzpgGwdXfHirMu/endpoint/' \
-H 'Authorization: Bearer AUTH_TOKEN' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://operational-webhook-destination.com/webhook/",
"filterTypes": [
"endpoint.updated",
"endpoint.deleted"
],
}'
请注意,在创建端点时,我们使用默认账户的 org ID 作为 app_id(或者在本例中是 uid)。
就是这样。现在你应该已经拥有了可用的操作 Webhooks。如果你以后想创建新端点或修改现有端点,只需为服务账户生成一个 JWT,然后像使用任何其他 Svix 账户一样使用该 JWT。
非对称签名
如上所述,推荐使用对称签名。但是,如果你确定需要非对称签名,请阅读以下关于设置非对称签名的说明。
配置密钥
默认情况下,Svix 服务器会为端点生成对称密钥,这意味着消息将使用对称密钥进行签名。要更改此默认设置,请将 default_signature_type 配置设置为 ed25519,如下所示:
default_signature_type = "ed25519"
此外,无论默认值如何设置,你都可以通过在端点上显式设置密钥来覆盖它。
要设置对称密钥,请将端点密钥设置为以 whsec_ 为前缀的密钥,例如 whsec_51TKyHBy5KFY1Ab98GQ8V60BkWnejkWy。
要设置非对称密钥,请将端点密钥设置为以 whsk_ 为前缀的有效 ed25519 base64 编码私钥,例如:whsk_6Xb/dCcHpPea21PS1N9VY/NZW723CEc77N4rJCubMbfVKIDij2HKpMKkioLlX0dRqSKJp4AJ6p9lMicMFs6Kvg==。
请注意,预期的私钥结构为:whsk_${base64(private_key + public_key)}。
出于测试目的,可以使用以下命令生成新的非对称密钥对:
$ svix-server asymmetric-key generate
Secret key: whsk_6Xb/dCcHpPea21PS1N9VY/NZW723CEc77N4rJCubMbfVKIDij2HKpMKkioLlX0dRqSKJp4AJ6p9lMicMFs6Kvg==
Public key: whpk_1SiA4o9hyqTCpIqC5V9HUakiiaeACeqfZTInDBbOir4=
签名方案
Svix 使用 ed25519(m) 对 webhook 消息进行签名,并以与对称签名相同的方式构建 m。
在验证消息时,你还应确保时间戳足够新,以限制重放攻击的可能性,如 对称验证文档 中所述。
关闭服务器
为了支持服务器的优雅关闭,在收到 SIGINT/SIGTERM 信号关闭之前,所有正在运行的任务都会完成。这通常耗时不到十秒。
与 Svix 托管服务的区别
我们将 Svix dispatcher 开源的主要目标之一是易用性。然而,托管的 Svix 服务由于我们的规模及其所需的基础设施而相当复杂。这种复杂性对绝大多数用户来说并无用处,并且会使该项目更难使用且功能受限。
因此,在发布之前,此代码已进行了调整,托管 dispatcher 支持的一些功能、优化和行为在此仓库中尚不可用。话虽如此,除了一些已知的不兼容性问题外,Svix 内部测试套件已通过。这意味着它们已经基本兼容,我们正在努力使其达到完全的功能对等。
Redis 任务队列 DLQ
在处理任务时,如果发生重复的内部错误,任务可能会进入死信队列(DLQ)。
Redis 不包含对 DLQ 的内置支持,因此在使用 Redis 队列后端时,Svix 会管理自己的 DLQ。因此,监控 DLQ 深度以确保其始终为空非常重要。您可以使用 svix.queue.depth_dlq 指标来执行此操作。非零值表示 DLQ 中存在需要处理的任务。
一旦错误条件结束,要重新驱动 DLQ,您可以向 /api/v1/admin/redrive-dlq/ 发送 POST 请求。
开发
查看我们的项目特定开发指南,开始对 Svix 进行开发!
贡献
贡献是开源世界运转的动力!我们非常欢迎并感激所有的贡献。
请参阅贡献指南以了解如何贡献。
贡献的快速指南:
- Fork 该项目
- 创建你的功能分支(
git checkout -b feature/some-feature) - 进行你的更改
- 提交你的更改(
git commit -m 'Implement an amazing feature.') - 推送到分支(
git push origin feature/some-feature) - 发起一个 Pull Request
License
基于 MIT License 分发。更多信息请参见 LICENSE。
发送指南
以下是使用 Svix 发送 Webhooks 的指南列表:
- 使用 Python 发送 Webhooks(也支持 Django 和 Flask)
- 使用 JavaScript 发送 Webhooks(也支持 NodeJS 和 Express)
- 使用 TypeScript 发送 Webhooks
- 使用 Go 发送 Webhooks
- 使用 Java 发送 Webhooks(也支持 Spring)
- 使用 Kotlin 发送 Webhooks
- 使用 Rust 发送 Webhooks
- 使用 C# 发送 Webhooks(也支持 ASP.NET)
- 使用 PHP 发送 Webhooks(也支持 Laravel)
- 使用 Ruby 发送 Webhooks
- 使用 Svix CLI 发送 Webhooks
Backed By
