密码存储是软件里少数几个真正存在标准答案的领域之一。答案早就公开了,一直有人维护,而且免费。可它同时又是最经常被做错的领域之一,原因很简单:那些错误的做法在某个年代确实是正确的,而后来没有人再回头看过一眼。 失败的样子很少稀奇。通常就是一套 2016 年按照 2012 年的建议搭起来的系统,到今天还在跑,还在接受登录请求,而自从当初写下那段哈希代码的人离职之后,就再也没有人打开过那个函数。它没出过故障,也没被审计过,所以从来不在任何人的待办清单上。 如果只带走一句话:用 Argon2id,实在不行就用 bcrypt。 本文其余部分都是细节。像 SHA-256 这样的通用哈希函数,无论你把它套用多少次,都不是密码哈希。它的快是设计目...
后端开发
关于后端开发的文章、指南和教程,为开发者和企业提供实用知识与技巧。也包括常见故障模式及其修复成本。
技术文档的失败方式非常具体,也非常好预测。有人在两周清闲的时间里写下一大堆,接着系统变了,没有人回头更新,一年之内那份文档就开始信心十足地讲着错误的内容。到了那个时候,它比什么都没有还要糟,因为相信它的读者会依据早已不成立的信息去动手。 常见的反应是号召大家多写一些,而这只会让同样的失败来得更快。有用的反应是少写,并且认真挑选写什么,因为真正的瓶颈不是写作的工夫,而是维护的工夫。文档从写完那一刻起,就开始被现实甩在后面。 判断一份文档该不该存在,唯一经得起时间的检验是: 当它变错的时候,会不会有人察觉?部署指南天天有人用,错误立刻就会浮出来。一份二十页的子系统说明只会被读一次,它的错误要等到十八个月后,有人照着它动手时才浮出来。没有...
可用性 SLA 看上去像一句承诺,实际运作起来却更像一份退款政策。供应商很清楚这一点。客户往往并不清楚,于是在签署服务级别协议时以为自己买到了可用性,而真正买到的,只是万一没拿到时的一点折扣。 这不一定是笔糟糕的交易。它只是与大多数人以为自己在签的那笔交易不同,而这个差别恰恰在系统宕机、有人追问合同究竟怎么写的那一刻显现出来。 三个九听上去接近完美,却允许每月 43 分钟的停机。 四个九允许四分钟。如果你的业务能吸收工作日下午 43 分钟的中断,99.9% 就足够了,不必为更高的数字付费。如果吸收不了,再多的九也帮不上忙,因为协议给你的是一笔积分,而不是阻止这次中断。 可用性 SLA 用分钟兑现的承诺百分比把一个非常大的区间压缩成看...
在小团队里,灾难恢复通常只剩下一份从来没人打开过的文档里的一行字:备份已经开启。这句话本身没错,却算不上任何问题的答案,因为它既没有说明真正出事时找回来的数据会有多旧,也没有说明恢复一次要花多长时间,更没有说明到今天为止究竟有没有人完整地做过一次恢复。 拥有备份和真的能恢复之间存在一段明显的距离,大多数故障正是在这段距离里升级成事故。一份存在、内容也够新、却从来没有被还原过的备份,本质上仍然只是一个假设;而你第一次去验证这个假设的时刻,恰好是发现它其实是错的最糟糕的时刻。 两个数字能把意见变成计划。 你能承受丢多少数据,又能承受停多久?这就是你的恢复点目标和恢复时间目标。只要业务一侧没有人把这两个数字说出口,关于备份频率的一切技术争...
关于 API 版本管理的争论,几乎总是从错误的一端开始:版本号该放在哪里。其实这是整个话题里后果最轻的一个决定。真正要紧的是,究竟哪些变更才需要一个新版本,而大多数团队恰恰在这里判断失误,而且是往掉以轻心的方向失误。他们发布了自认为纯属新增的东西,然后某个客户端就坏了。 有用的思维模型是:你的 API 是一份承诺,规定了调用方可以依赖什么。如果一次变更让一个讲道理的调用方原本依赖的东西失效了,那它就是破坏性的。而调用方依赖的东西,远远多于你的文档明确允许他们依赖的范围。 让所有人都栽跟头的那种变更: 往响应里加一个字段。它只是新增,按理说不可能弄坏一个写得规范的客户端,可它偏偏经常弄坏真实的客户端,因为其中有些客户端会严格校验响应,...
数据库性能的排查工作,通常从有人提议换一台更大的实例开始,又通常以这样一个发现结束:每次加载页面时,有一条查询都在对 400 万行做顺序扫描。瓶颈从来不是硬件,瓶颈是执行计划。 这个模式重复得足够稳定,值得当作默认假设写下来。当应用很慢而数据库又很忙时,原因几乎总是少数几条具体的查询,而不是整体容量不足;把机器换大,只能把问题掩盖到表再次长大的那一刻为止。 动手改之前,先量。 凭猜测去优化一条查询,正是团队花掉整整一周添加索引、结果写入变慢而读取一点没快的原因。任何数据库都能告诉你哪些语句消耗的总时间最多。从那里开始,修掉排在最前面的那条,然后再量一次。这样反复两三轮,事故通常就结束了。 数据库性能始于找出那条查询总时间比最坏单次更...
Cloudflare Queues 解决的是每个无服务器应用迟早都会撞上的那个问题:一个请求到达,触发了一段用户本不该等待的工作。发送确认邮件、给上传的图片改尺寸、把记录同步到第三方服务。这些活儿的共同点是:它们必须发生,但并不需要在用户按下按钮的那一刻发生。在传统服务器上,你把这类活儿交给一个后台工作进程就行了。可是在 Workers 上,请求处理完就结束,根本没有可以交出去的常驻进程。 常见的几种绕开办法,比看上去更糟。把工作放在请求里同步做完,等于让用户去等一个邮件服务商的响应。向另一个 Worker 发出请求却不等待它,只要发起方的调用先结束,这个任务就丢了。这两种做法都扛不住服务商的一次故障。 队列真正给你的是什么: 是持...
Cloudflare Hyperdrive 的存在,是为了解决一个非常具体、也毫不光鲜的问题:一个在 200 座城市里运行的 Worker,去和一座城市里的那一个 Postgres 数据库对话,会比同一条查询从紧挨着这台数据库的服务器发出更慢。不是慢一点点,而往往是慢上好几倍,而且这些原因和查询本身怎么写完全没有关系。 当一个无服务器应用显得迟钝时,人们的第一反应通常是怪查询规划器,或者再加一个索引。但在与某个区域数据库通信的 Workers 上,查询本身通常没有毛病。真正出问题的是连接。 Hyperdrive 真正修好的东西: 建立一次数据库连接的代价,而且这笔代价要在每一个请求上重新付一遍。一条 Postgres 连接在第一行数...
Cloudflare Workers 与 AWS Lambda 都是无服务器计算平台,但它们的起点不同。Lambda 是庞大 AWS 生态系统中确立的无服务器标准;Workers 则是边缘原生的,为低延迟和全球分发而生。2026 年,两者都很出色,正确的选择取决于你的工作负载和现有技术栈。本指南从真正重要的维度对比 Cloudflare Workers vs AWS Lambda。 要点速览(TL;DR) Workers 在轻量的 V8 isolates 上于 edge 运行,cold start 几乎为零,并默认全球分发 Lambda 在 AWS 区域中以 microVM 模型运行,支持众多语言运行时,并与 AWS 生态系统深度集...
Cloudflare Workers 让你无需管理服务器,就能在靠近用户的边缘运行后端代码。对 API 而言,近乎为零的冷启动、全球分发与紧密集成的存储三者结合,使 Workers 在 2026 年成为极具吸引力的平台。本指南讲解 Cloudflare Workers API 的结构,以及它与传统后端有何不同。 要点速览 Cloudflare Workers 在边缘的 Cloudflare 全球网络上运行你的代码,因此请求可在靠近用户处以近乎为零的冷启动被处理 Worker 通过 fetch 处理器处理传入请求;你按方法与路径进行路由,并返回标准的 Response 对象 Workers 直接绑定到存储:D1(SQLite)、KV(...