分布式可靠性:在超时与部分失败中做取舍
单进程函数失败时,调用者往往能看到异常;跨网络调用超时后,调用者却不知道对端是否完成。分布式设计的起点是部分失败:一部分节点仍在工作,另一些通信中断,而不同节点看到的状态可能不同。 ...
单进程函数失败时,调用者往往能看到异常;跨网络调用超时后,调用者却不知道对端是否完成。分布式设计的起点是部分失败:一部分节点仍在工作,另一些通信中断,而不同节点看到的状态可能不同。 ...
服务测试不止检查“请求返回 200”。预约返回成功但库存扣了两次,或者越权用户看到他人记录,都是状态与边界错误。先列不变量,再选能观察它的测试层级。通用测试与调试介绍证据与最小复现,这里关注跨 HTTP、数据库和并发的服务行为。 ...
这条路线组织 Java 和 Go 都需要的后端知识。知识点正文只有一份;语言练习分别进入 Java/Spring 路线与 Go 服务路线。不必同时学完两门语言才开始实践。 先确认基础 能写函数、读写结构化数据并使用命令行;不熟悉 HTTP、进程线程或关系数据时,先完成第一阶段。每个阶段的节点可直接跳到正文,正文里的前置项用来发现还缺哪块基础。 ...
缓存保存可以重新获得的数据,用额外复杂度换取较低的读取成本。设计前先回答三个问题:允许旧多久、缓存不可用时怎样降级、哪些数据不能只放缓存。库存余额和支付状态通常仍以数据库中的受约束事实为准,不能把缓存命中当作强一致性的证据。 ...
能在开发机启动只是服务生命周期的开始。交付还要回答:部署的是哪份代码、配置从哪里来、旧版本能否共存、怎样判断异常、数据怎样恢复。这里以单服务为起点;容器与编排工具帮助管理运行过程,不会自动补齐业务恢复能力。 ...
身份验证回答“当前请求是谁发出的”,授权回答“这个身份能对这份数据做什么”。用户已经登录,不代表可以读取任意预约 ID。服务端必须对每次对象访问检查所有者、角色或明确的共享关系,不能依靠前端隐藏按钮。 ...
事务把若干读写组织成一次提交,但“包进事务”不意味着所有并发问题消失。必须先说清不变量:库存不为负、同一次预约只扣一次、预约与对应事件一起落库。隔离级别决定事务能观察到怎样的并发状态,约束和锁则帮助你维护具体规则。 ...
数据表应保存需要长期成立的事实,而不是照着页面字段机械建表。一个页面可以同时显示用户、商品和预约;它们的生命周期不同,不能因此塞进同一张宽表。关系数据基础介绍关系和 SQL,这里把它们落实到业务约束。 ...
索引保存额外的数据组织方式,使数据库更快找到候选行;它同时增加空间和写入维护成本。优化的目标是完成具体查询所需的工作量,而不是让所有 SQL 都出现 Index Scan。小表全扫、大范围聚合走顺序扫描,都可能比随机访问索引更便宜。 ...
消息系统把“接收请求”与“完成工作”拆开,可以吸收短时流量,也让消费者独立伸缩。代价是必须描述延迟、丢失、重复、顺序与恢复。把函数调用换成队列,并不会自动得到可靠性。 ...