题干与适用场景
这道题考察你能否把传输层的低延迟优化转化为清晰的业务安全边界。TLS 1.3 早期数据可能在连接建立前发送,但 RFC 8470 明确提醒它存在重放风险;因此不能仅按 HTTP 方法名称决定请求是否安全。回答需要覆盖请求分类、状态机、幂等性、缓存与代理、客户端重试、监控和降级。
面试官考察什么
- 能否区分“重复读取无害”和“重复执行副作用”两类语义。
- 能否把早期数据限制在明确的安全集合,并为不确定请求提供可解释的拒绝路径。
- 能否设计 425、幂等键、请求去重和重试退避之间的协作。
- 能否说明代理链、日志、指标、回滚和逐步放量的风险控制。
回答前需要澄清的问题
先确认哪些请求可能携带 early data,TLS 终止点在哪里,入口后是否还有代理或消息重试。哪些操作会改变余额、库存、订单、权限或发送通知?业务是否已有幂等键、请求状态表和唯一约束?客户端、SDK、网关是否理解 425?重试由谁发起、最多几次、是否使用指数退避和抖动?如果去重存储不可用,是拒绝、降级到完整握手,还是允许只读请求继续?
30 秒回答框架
我会默认把带副作用或无法证明幂等的请求排除在 early data 之外。边缘层识别 early data 并把信号安全传给应用;安全读取可继续,订单、扣款和权限变更则返回 425 或要求完整握手。对确需低延迟的写入,使用客户端提供的幂等键、服务端唯一约束和短期结果缓存,把“已执行”和“处理中”状态持久化。客户端只对明确可重试的结果做带上限和抖动的退避,逐步放量并监控重复执行、425、重试量和业务异常。
分步骤深入解答
1. 定义 early data 的信任边界
在 TLS 终止层识别请求是否使用 early data,并以受保护的内部信号传递给后端,不能让公网客户端任意伪造“安全请求”标记。代理、缓存和服务间调用要明确是否会复制或延迟请求。默认策略应是未识别、信号丢失或路径不确定时按高风险处理。
2. 依据业务副作用分类
无状态读取、重复结果不影响资源的查询通常更容易接受;创建订单、扣款、库存扣减、权限变更、发送消息和触发外部调用都应视为可重放风险。即便方法是 PUT 或 DELETE,也要确认实现确实满足幂等语义;POST 不代表一定不能幂等,关键在业务状态模型与唯一约束。
3. 设计 425 与完整握手降级
对不允许 early data 的路径返回 425 Too Early,并提供可重试的响应头与文档约定,让客户端先完成完整握手再重发。网关应避免在收到 425 后自动无限重试;需要记录原始请求是否可能已到达应用,防止边缘层和客户端各自重试造成放大。无法识别客户端能力时,选择显式失败优于静默执行。
4. 用幂等键和状态机抵御重复写入
幂等键必须绑定租户、操作类型和请求参数摘要,服务端用唯一约束保存处理中、成功和失败结果。并发到达同一键时,一个请求取得处理权,其他请求读取状态或等待有限时间;参数不一致直接拒绝。结果缓存要设定保留期,避免旧结果与业务重试窗口不匹配。数据库提交与外部副作用之间仍需采用事务外发、状态轮询或可补偿设计。
5. 约束重试与代理行为
客户端只在响应语义允许且请求满足幂等条件时重试,使用截断指数退避、抖动和总次数上限。网关、SDK、队列消费者不能叠加无界重试;应区分 425、连接失败、限流和业务拒绝。对高价值写操作,可让客户端查询幂等键状态,而不是重新发送原始副作用请求。
6. 监控、放量与降级
先在只读路径和少量租户启用,保留按路由、客户端和地区关闭的开关。监控 early-data 请求量、425 比例、重复键冲突、重复扣款或库存异常、重试放大系数、握手降级延迟和去重存储错误。发现指标越过阈值时停止放量、关闭 early data 或强制完整握手,并保留审计样本用于判断请求是否实际执行。
高质量示范回答
我会把 early data 当作可能被重放的输入,而不是普通 HTTPS 请求。入口识别并保护传输信号,读取类请求在风险可接受时继续;下单、扣款、库存、权限和外部通知默认返回 425,要求完整握手。对确需低延迟的写入,客户端必须提供绑定租户、操作和参数摘要的幂等键,服务端用唯一约束和状态机保存处理中、成功与失败结果,参数冲突直接拒绝。425、连接失败和限流分别定义重试条件,客户端使用有上限的指数退避和抖动,网关不做无限自动重试。先小范围放量,监控 425、重复键、业务重复执行、重试放大、降级延迟和去重存储故障;出现异常就关闭 early data 或强制完整握手,并核对审计记录。
常见错误
- 认为 TLS 已加密,所以 early data 不会被重放。
- 只按 GET、POST 等方法名分类,不检查实际业务副作用。
- 收到 425 后由网关和客户端同时无限重试。
- 幂等键不绑定租户和参数,导致跨请求串用或参数冲突被吞掉。
- 只缓存成功结果,不记录处理中状态和失败可重试语义。
- 只看延迟收益,不监控重复扣款、库存异常和重试放大。
- 没有按路由关闭、完整握手降级和审计核对方案。
追问及应对
425 和 429 有什么区别?
425 表示请求在当前 early-data 条件下过早,客户端应在完整握手后重试;429 表示请求受到频率或配额限制。两者的重试条件、等待提示和监控含义不同,不能用同一个自动重试分支处理。
如果客户端不支持 425 怎么办?
对关键写路径在网关直接拒绝 early data 或强制完整握手,避免依赖客户端正确解释状态码。升级 SDK 时提供兼容策略;对只读路径可以继续服务,但要记录客户端能力和风险边界。
幂等键存储挂了,是否允许扣款继续?
不能在无法证明去重的情况下继续高风险副作用。可以返回可重试错误、降级到完整握手后再次检查,或把请求转为可查询的待处理状态;决策要以业务损失上限和恢复路径为依据。
早期数据请求已经到达应用,随后返回 425,会不会仍然执行?
会有这种竞态,所以应用必须在执行副作用前再次检查 early-data 信号和幂等状态,不能把 425 当作撤销。所有副作用都通过状态机与唯一约束提交,并用审计记录确认是否已执行。