实战:用取消参数使 Go net/http 服务更灵活( 四 )


这里是执行的代码:
// Taken from: #L486-L498func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { return WithDeadline(parent, time.Now().Add(timeout))}// Taken from: #L418-L450func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {// *Snipped*c :=--tt-darkmode-color: #EF7060;">WithDeadline 函数设置了一个 d 到达之后执行的函数 。 当到达截止时间后 , 它调用 cancel 方法处理上下文 , 此方法会关闭上下文的 done 通道并设置上下文的 timer 属性为 nil 。
Done 通道的关闭有效地取消了上下文 , 使我们的 slowAPICall 函数终止了它的执行 。 这就是 TimeoutHandler 终止耗时长的处理进程的原理 。
(如果你想阅读上面提到的源码 , 你可以去看 `cancelCtx` 类型[15] 和`timerCtx` 类型[16])
有弹性的 net/http 服务连接截止时间提供了低级的细粒度控制 。 虽然它们的名字中含有“超时” , 但它们并没有表现出人们通常期望的“超时” 。 实际上它们非常强大 , 但是使用它们有一定的门槛 。
另一个角度讲 , 当处理 HTTP 时 , 我们仍然应该考虑使用 TimeoutHandler 。 Go 的作者们也选择使用它 , 它有多种处理 , 提供了如此有弹性的处理以至于我们甚至可以对每一个处理使用不同的超时 。 TimeoutHandler 可以根据我们期望的表现来控制执行进程 。
除此之外 , TimeoutHandler 完美兼容 context 包 。 context 包很简单 , 包含了取消信号和请求相关的数据 , 我们可以使用这些数据来使我们的应用更好地处理错综复杂的网络问题 。
结束之前 , 有三个建议 。 写 HTTP 服务时 , 怎么设计超时:

  1. 最常用的 , 到达 TimeoutHandler 时 , 怎么处理 。 它进行我们通常期望的超时处理 。
  2. 不要忘记上下文取消 。 context 包使用起来很简单 , 并且可以节省你服务器上的很多处理资源 。 尤其是在处理异常或网络状况不好时 。
  3. 一定要用截止时间 。 确保做了完整的测试 , 验证了能提供你期望的所有功能 。
更多关于此主题的文章:
  • “The complete guide to Go net/http timeouts” on Cloudflare's blog[17]
  • “So you want to expose Go on the Internet” on Cloudflare's blog[18]
  • “Use http.TimeoutHandler or ReadTimeout/WriteTimeout?” onStackoverflow[19]
  • “Standard net/http config will break your production environment” onSimon Frey's blog[20]
via:
作者:Ilija Eftimov[21]译者:lxbwolf[22]校对:polaris1119[23]
本文由 GCTT[24] 原创编译 , Go 中文网[25] 荣誉推出
参考资料[1]
conn 类型: #L248
[2]
函数: #L1765
[3]
处理每一个请求: #L1822
[4]
timeout 值: #L946-L958
[5]
net/http 包:
[6]
TimeoutHandler: /#TimeoutHandler
[7]
Cloudflare:
[8]
context:
[9]
golang.org/x/net/context:
[10]
Go Sub-repository Packages:
[11]
Golang's blog:
[12]
Context 方法: /#Request.Context
[13]
Context 类型: #Context
[14]
timeoutHandler.ServeHTTP 方法: #L3217-L3263
[15]
cancelCtx 类型: #L389-L416
[16]
timerCtx 类型: #L472-L484
[17]
Cloudflare's blog:
[18]
Cloudflare's blog:
[19]
Stackoverflow:
[20]
Simon Frey's blog:
[21]
Ilija Eftimov:
[22]
lxbwolf:
[23]
polaris1119:
[24]
GCTT:
[25]
【实战:用取消参数使 Go net/http 服务更灵活】Go 中文网:
实战:用取消参数使 Go net/http 服务更灵活文章插图