你的重试循环假设第一次请求失败了。大概率并没有。
超时或崩溃并不意味着你的 API 请求已经丢失。本文介绍幂等键(idempotency key)如何让重试变得安全,以及真正防止重复请求的数据库存储模式。
你的服务在处理 请求时中途崩溃。客户端看到超时,于是重试。结果出现了两笔扣款。客户很生气。数据库是一致的。但业务逻辑不是。 这不是边缘情况。这是分布式系统的默认行为。网络丢包。容器在请求中途被 OOM 杀掉。负载均衡器对已经到达后端的请求返回 502。如果你的 API…
4 posts
超时或崩溃并不意味着你的 API 请求已经丢失。本文介绍幂等键(idempotency key)如何让重试变得安全,以及真正防止重复请求的数据库存储模式。
你的服务在处理 请求时中途崩溃。客户端看到超时,于是重试。结果出现了两笔扣款。客户很生气。数据库是一致的。但业务逻辑不是。 这不是边缘情况。这是分布式系统的默认行为。网络丢包。容器在请求中途被 OOM 杀掉。负载均衡器对已经到达后端的请求返回 502。如果你的 API…
内存中的互斥锁在服务器重启后随即消失。本文介绍带有 fencing token 和 TTL 的分布式租约如何防止崩溃后的重复执行,以及它们在哪里仍然会失效。
你的 无法挺过 。它也无法挺过 OOM、部署滚动更新或节点重启。进程退出的瞬间,锁就消失了。如果这个锁正在保护一个定时任务、数据迁移或主节点选举,那么你现在会有两个进程都坚信自己是唯一在运行的那个。 这不是你的互斥锁有 bug。这是一个范畴错误。进程本地的锁无法保护集群范围的资源。…
大多数熔断器库都会启动后台线程来探测恢复。你根本不需要它们。本文介绍一种请求驱动的设计,在消除所有后台开销的同时,不牺牲正确性。
我审查过的每一个生产环境熔断器,最终都会拉起一条后台线程。它可能是 Go 的 goroutine、Java 的 ,或是 Rust 的 tokio task。干的事情永远一样:每隔几秒唤醒一次,检查下游服务是否已经恢复,然后把状态从 OPEN 切回 CLOSED。…
Crash-only 软件将每一次失败视为崩溃,将每一次启动视为恢复。对于 Web 服务来说,这意味着删除你的关闭逻辑,并设计出能在 kill -9 下存活的状态。
你的 Web 服务有一个关闭处理器。它会刷写缓冲区、关闭连接、写入检查点。也许你曾经测试过一次。在生产环境中,它可能只在每年一次的有计划部署时才会运行。其余时间,你的服务死于 OOM kill、节点驱逐、断电,或是超时后被 SIGKILL 的部署。 Crash-only…