Appearance
一次 HTTP 调用经历什么:Lifecycle、Connection Pool 与 Timeout Layers
前置:Durable Run Identity;Runtime State Persistence
核心问题:一次 HTTP 请求慢,到底是 connect、pool wait、server processing 还是 read 卡住,Timeout 应怎样按层配置?
“HTTP 超时”可能发生在拿连接、建连、写请求或读响应等不同阶段;不拆分就无法判断是本地排队、网络问题还是远端服务变慢。Harness 因此需要长期复用的 HTTP client,而不是每个 Tool Call 临时创建一个 client。
Mental Model
text
Request → connection pool → HTTP exchange/stream → event parser → Runtime observation → cancellation/backpressureHTTP/streaming 的真实链路是 connection acquisition → request headers/body → response/stream events → disconnect/timeout/cancel → connection reuse/close。
HTTP Request Lifecycle
HTTP Request Lifecycle 从连接池获取/建立连接、发送 headers/body、等待 response headers/body/stream,到释放或关闭连接结束;每个阶段都有独立 timeout、错误和可观测点。
不同阶段故障需要不同 timeout/metric。
Connection Reuse
Connection Reuse 指一次请求结束后把仍健康的连接放回 pool,后续请求省掉重复 DNS/TCP/TLS 建连。复用不是永久有效:idle timeout、服务端主动关闭和 endpoint/DNS 变化都会使旧连接失效,因此 client 既要复用也要能淘汰连接。
HTTP Connection Pool
Connection Pool 在“复用连接”之外还承担并发槽位:请求可能先等待 acquire,拿到连接后才进入 connect/write/read。pool_wait 因此是客户端本地排队指标,应与远端处理时间分开观测。
Timeout Layers
HTTP Timeout Layers 把等待拆成 pool acquire、connect、write、read/idle 与 overall deadline 等阶段。分层的价值是准确定位瓶颈,并为不同失败阶段选择不同 retry/cancel 策略。
各层 timeout 应有明确错误类型,并受整个 Run deadline 约束。
在 Shadow Harness 中怎么落地
在 Harness Adapter 中,一次调用至少记录 pool_wait / connect / write / TTFB-read / overall_deadline,并把阶段化错误归一后交给 Module 11 的 reliability policy。
text
ToolExecutor
→ HttpClientPool.acquire
→ connect / reuse
→ write request
→ read response / stream
→ release / close
→ normalized observationTransport lifecycle 只负责网络调用本身;Run 的 durable lifecycle 仍由 Runtime 管理。
Failure Modes
无限并发把瓶颈推到下游 Pool/Provider
症状: 无依赖任务全部 create task,不考虑 DB/HTTP/provider 容量。
为什么危险: 429、pool wait、tail latency 恶化。
处理: 分层 concurrency limit + bounded queue,以真实 capacity 为 scheduler 输入。
如何验证
| Case | 断言 |
|---|---|
| 无限并发把瓶颈推到下游 Pool/Provider | 逐步提高并发,超过拐点前 admission control 生效。 |
自测
- 请求经常卡在连接建立前而不是服务端处理阶段。connection pool、connect timeout、read timeout 中该先看哪一个?
- 连接池太小与下游本身太慢,在 metrics 上会怎样表现不同?