Skip to the content.

HTTP 请求超时

问题和触发条件

原来的共享 HTTP 宿主没有请求处理期限。Reference 的数据库和消息接口已经接收 CancellationToken,但客户端保持连接且下游迟迟不返回时,服务端不会主动取消这些工作。单纯设置 HttpClient.Timeout 只约束调用方;服务端仍可能继续执行查询或写入。

ASP.NET Core 的请求超时中间件在期限到达时取消 HttpContext.RequestAborted。端点和下游调用必须继续传递这个 token 并响应取消。中间件不能强制结束忽略取消的同步或异步工作;如果响应已经开始,也不能把它改写成完整的 504 响应。因此这里的超时是服务端协作取消机制,不是对任意代码的强制中断。

本次方案

AddPlatformRequestTimeouts 和 UsePlatformRequestTimeouts 显式接入 ASP.NET Core 内置的请求超时组件。宿主可以直接在 RequestTimeoutOptions 中设置默认策略或命名策略,再用 WithRequestTimeout 关联端点或路由组。不配置策略时,注册中间件本身不会给请求设定期限。

Reference 的 Http:RequestTimeouts:Enabled 默认为 false。启用后,所有业务 API 端点共用 reference-api-timeout 策略,默认期限为 30 秒;可以通过 Http:RequestTimeouts:Seconds 设置正整数秒数。存活和就绪端点没有附加该策略。无效的布尔值或非正秒数会在服务组合阶段报错。策略超时且端点按约定响应取消时,未开始的响应返回 504。

Reference 的管线顺序是:转发头、路由、CORS、请求日志、请求超时、认证、授权、限流、端点。超时中间件需要位于路由后,才能看到端点策略;它放在认证、授权和限流前,因此这些处理时间也属于 API 期限。授权先拒绝 401、403,限流再按已验证身份分区。请求日志包住超时中间件,能够记录超时响应。

情况 行为
API 在期限内完成 返回原有响应。
API 超时,端点观察取消且响应尚未开始 RequestAborted 被取消;中间件返回 504。
客户端先取消请求 客户端的调用取消;服务端观察 RequestAborted,不会把这次取消当作超时响应交给客户端。
Reference 健康端点 不使用 API 命名超时策略。
宿主设置全局默认策略 未指定其他策略的端点也会超时;可用 DisableRequestTimeout 显式豁免。

新增代码使用框架内置组件、静态类型和显式读取配置,没有引入运行时反射或动态代码生成。这项工作补充行为边界,未进行性能优化,也没有前后吞吐数据。

验证与后续

TestServer 验证了慢端点取消 RequestAborted 并返回 504、正常请求成功、健康端点豁免、调用方先取消、Reference 的 API/健康端点策略元数据,以及配置错误在启动时被拒绝。这些测试验证中间件和端点接线;它们不证明真实数据库、代理或长连接在超时后的资源释放时间。

不同 API 的合理期限可能相差很大。当前 Reference 为控制配置范围只提供一个 API 策略;确有需要时,可以为特定端点指定另一命名策略。对写请求还要明确事务和幂等语义:取消信号到达时,外部依赖可能已经提交,客户端收到 504 不代表写入一定失败。这需要由写请求幂等功能单独处理。