Rust in Everything
基于 tower 0.5.3

常见坑

每一章对着一个报错或者一个现象:先用一个最小的程序把它复现出来,再到源码里找它是在哪一行产生的,最后给出修法,修法也跑一遍。机制本身在前面的章节讲过的,这里只链过去,不再重复。

  1. poll_ready must be called first:没就绪就 call。ConcurrencyLimit 一定 panic,RateLimit 只在窗口用完后 panic,Buffer 的 panic 信息来自 tokio-util。实际代码里多半是在 call 里 clone 了内层,修法是 mem::replace。
  2. Clone is not satisfied:axum 的 Router::layer 和 Retry 都要内层 Clone,RateLimit 没有。套 Buffer 能编译,但在 axum 里限流的范围变成了每个连接。
  3. buffer's worker closed unexpectedly 与 buffered service failed:worker 所在的运行时没了,或者内层 poll_ready 报过一次错。两种都是永久的。
  4. 请求卡住不动:Buffer 的通道位置被 ready 了却不 call 的句柄占光;或者 Buffer 里的 ConcurrencyLimit 许可在一个没人 poll 的响应 future 里。
  5. request timed out,内层却只用了 100ms:Timeout 从 call 开始计时,套在 Buffer 外面就把排队算进去;等 ConcurrencyLimit 许可在 poll_ready 里,放哪都不计。
  6. 401 响应没有 x-frame-options:层的顺序反了。ServiceBuilder 先写的在外层,axum 的 Router::layer 后写的在外层。
  7. fast 请求等了 2000ms:Steer 要所有后端都就绪才算就绪,一个后端忙,整个路由都等。
  8. service overloaded:LoadShed 的 Overloaded 错误。除了真过载,没 ready 就 call、里面有别的 Pending 来源、被拒绝的实例攥着许可,都会让它出现。
  9. the method oneshot exists for struct Filter, but its trait bounds were not satisfied:AsyncFilter::layer 返回的是同步的 FilterLayer,要用 AsyncFilterLayer::new 或 ServiceBuilder::filter_async。
flowchart TB
  asm["装配:类型和顺序"] --> p2["2 缺 Clone"]
  asm --> p6["6 层的顺序"]
  asm --> p9["9 AsyncFilter::layer"]
  rdy["就绪主线"] --> p1["1 没就绪就 call"]
  rdy --> p3["3 Buffer 的错误"]
  rdy --> p4["4 Buffer 卡住"]
  rdy --> p7["7 Steer 队头阻塞"]
  rdy --> p8["8 service overloaded"]
  req["请求主线"] --> p5["5 超时算进排队"]

前五章都和 Buffer 或 poll_ready 预留的资源有关:谁占着、占在哪个实例上、什么时候还。读之前最好先读过 Service trait 和 Buffer。

💬 关联讨论

发起讨论
加载中...